astro-perp-ccxt-dev
Version:
1,183 lines (1,181 loc) • 109 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/astros.js';
import { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, DDoSProtection, InsufficientFunds, NotSupported, InvalidOrder, AuthenticationError, RequestTimeout, RateLimitExceeded, OperationFailed } 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';
// ---------------------------------------------------------------------------
/**
* @class astros
* @augments Exchange
*/
export default class astros extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'astros',
'name': 'Astros',
'countries': ['SG'],
'version': 'v1',
'rateLimit': 75,
'certified': true,
'pro': true,
'userAgent': this.userAgents['chrome'],
'has': {
'CORS': undefined,
'spot': false,
'margin': false,
'swap': true,
'future': false,
'option': false,
'addMargin': true,
'borrowCrossMargin': false,
'borrowIsolatedMargin': false,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': true,
'closeAllPositions': false,
'closePosition': true,
'createConvertTrade': false,
'createDepositAddress': false,
'createMarketBuyOrderWithCost': false,
'createMarketOrderWithCost': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrders': true,
'createOrderWithTakeProfitAndStopLoss': false,
'createPostOnlyOrder': true,
'createReduceOnlyOrder': false,
'createStopLimitOrder': false,
'createStopLossOrder': false,
'createStopMarketOrder': false,
'createStopOrder': false,
'createTakeProfitOrder': false,
'createTrailingAmountOrder': false,
'createTrailingPercentOrder': false,
'createTriggerOrder': false,
'editOrder': false,
'fetchAccounts': false,
'fetchBalance': true,
'fetchBorrowInterest': false,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchCanceledAndClosedOrders': false,
'fetchCanceledOrders': false,
'fetchClosedOrders': true,
'fetchConvertCurrencies': true,
'fetchConvertQuote': true,
'fetchConvertTrade': false,
'fetchConvertTradeHistory': true,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': false,
'fetchDeposit': false,
'fetchDepositAddress': false,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': false,
'fetchDepositsWithdrawals': false,
'fetchDepositWithdrawFee': 'emulated',
'fetchDepositWithdrawFees': false,
'fetchFundingHistory': false,
'fetchFundingInterval': false,
'fetchFundingIntervals': false,
'fetchFundingRate': true,
'fetchFundingRateHistory': true,
'fetchFundingRates': false,
'fetchIndexOHLCV': false,
'fetchIsolatedBorrowRate': false,
'fetchIsolatedBorrowRates': false,
'fetchLedger': false,
'fetchLeverage': true,
'fetchLeverageTiers': false,
'fetchLiquidations': false,
'fetchLongShortRatio': false,
'fetchLongShortRatioHistory': false,
'fetchMarginAdjustmentHistory': false,
'fetchMarginMode': false,
'fetchMarketLeverageTiers': false,
'fetchMarkets': true,
'fetchMarkOHLCV': true,
'fetchMarkPrice': true,
'fetchMyLiquidations': false,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterest': false,
'fetchOpenInterestHistory': false,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrderBooks': false,
'fetchOrders': false,
'fetchOrderTrades': false,
'fetchPosition': true,
'fetchPositionHistory': 'emulated',
'fetchPositionMode': false,
'fetchPositions': true,
'fetchPositionsHistory': false,
'fetchPositionsRisk': false,
'fetchPremiumIndexOHLCV': false,
'fetchStatus': false,
'fetchTicker': false,
'fetchTickers': false,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': false,
'fetchTradingFees': false,
'fetchTransactions': false,
'fetchTransfer': false,
'fetchTransfers': false,
'fetchWithdrawAddresses': false,
'fetchWithdrawal': false,
'fetchWithdrawals': false,
'reduceMargin': true,
'repayCrossMargin': false,
'repayIsolatedMargin': false,
'setLeverage': true,
'setMargin': false,
'setMarginMode': false,
'setPositionMode': false,
'signIn': false,
'transfer': false,
'withdraw': undefined,
},
'timeframes': {
'1m': '1MIN',
'5m': '5MIN',
'15m': '15MIN',
'30m': '30MIN',
'1h': '1HOUR',
'2h': '2HOUR',
'4h': '4HOUR',
'8h': '8HOUR',
'12h': '12HOUR',
'1d': '1DAY',
'1w': '1WEEK',
'1M': '1MONTH',
},
'urls': {
'logo': 'https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/_next/image?url=%2Fassets%2Fbeta-logo.png&w=384&q=75',
'www': 'https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/',
'doc': [
'https://www.astros.com/api-doc/common/intro',
'https://www.astros.com/api-doc/spot/intro',
],
'api': {
'public': 'https://dasprkkzjjkl7.cloudfront.net/api/third',
'private': 'https://dasprkkzjjkl7.cloudfront.net/api/third',
},
'referral': 'https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/perp?referralCode=WK4OQL',
},
'api': {
'public': {
'get': {
'info/ping': 1,
'info/time': 1,
'info/markPrice': 1,
'info/trades': 1,
'info/pairs': 1,
'info/depth': 1,
'info/kline': 1,
'v1/market/funding/history': 1,
'v1/market/funding/current': 1,
},
},
'private': {
'get': {
'v1/trade/fillHistory': 1,
'v1/orders/histories': 1,
'v1/trade/getUserLever': 1,
},
'post': {
'hot/order/balance': 1,
'order/selectContractCurrentEntrustList': 1,
'order/selectContractMatchPairList': 1,
'order/queryOrder': 1,
'hot/order/selectContractPositionList': 1,
'hot/order/create': 1,
'hot/order/batchCreate': 1,
'order/cancelEntrust': 1,
'order/cancelEntrustByCli': 1,
'order/batchCancelEntrust': 1,
'order/cancelAll': 1,
'order/callMarginAmount': 1,
'hot/order/closeOrder': 1,
'position/updatePositionType': 1,
},
},
},
'fees': {
'swap': {
'taker': this.parseNumber('0.006'),
'maker': this.parseNumber('0.004'),
},
},
'requiredCredentials': {
'apiKey': true,
'secret': true,
'password': false,
},
'exceptions': {
'exact': {
'400': BadRequest,
'401': AuthenticationError,
'403': NotSupported,
'404': NotSupported,
'405': NotSupported,
'415': BadRequest,
'429': RateLimitExceeded,
'500': ExchangeNotAvailable,
'503': ExchangeNotAvailable,
'1000': ExchangeError,
'2002': BadRequest,
'2001': BadRequest,
'3007': AuthenticationError,
'4004': AuthenticationError,
'4012': AuthenticationError,
'2011': RequestTimeout,
'2007': DDoSProtection,
'2329': OnMaintenance,
'2316': ExchangeError,
'2307': ExchangeError,
'2302': InvalidOrder,
'2102': InsufficientFunds,
'2103': InvalidOrder,
'2125': InvalidOrder,
'2126': InvalidOrder,
'2104': ExchangeError, // { "code": 2104, "message": "Position expired" }
},
'broad': {
'invalid size, valid range': ExchangeError,
},
},
'precisionMode': TICK_SIZE,
'commonCurrencies': {},
'options': {
'timeDifference': 0,
'adjustForTimeDifference': false,
'timeframes': {
'swap': {
'1m': '1MIN',
'5m': '5MIN',
'15m': '15MIN',
'30m': '30MIN',
'1h': '1HOUR',
'2h': '2HOUR',
'4h': '4HOUR',
'8h': '8HOUR',
'12h': '12HOUR',
'1d': '1DAY',
'1w': '1WEEK',
'1M': '1MONTH',
},
},
'fetchMarkets': [
'swap', // there is future markets but they use the same endpoints as swap
],
'defaultType': 'swap',
'createMarketBuyOrderRequiresPrice': true,
'broker': undefined,
'sandboxMode': false,
'defaultTimeInForce': 'GTC', // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
},
'features': {
'default': {
'sandbox': true,
'createOrder': {
'marginMode': true,
'triggerPrice': undefined,
'triggerPriceType': undefined,
'triggerDirection': undefined,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'GTC': true,
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'trailing': false,
'leverage': true,
'marketBuyByCost': false,
'marketBuyRequiresPrice': false,
'selfTradePrevention': false,
'iceberg': false, // todo implement
},
'createOrders': {
'max': 10,
},
'fetchMyTrades': {
'marginMode': false,
'limit': 100,
'daysBack': undefined,
'untilDays': 7,
'symbolRequired': true,
},
'fetchOrder': {
'marginMode': false,
'trigger': true,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': 500,
'trigger': true,
'trailing': false,
'symbolRequired': true,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'limit': 100,
},
'fetchOHLCV': {
'limit': 1000,
},
},
'spot': {
'extends': 'default',
},
'forDerivatives': {
'extends': 'default',
'createOrder': {
// todo: implementation needs unification
'triggerPriceType': undefined,
'attachedStopLossTakeProfit': {
// todo: implementation needs unification
'triggerPriceType': undefined,
'price': false,
},
},
},
'swap': {
'linear': {
'extends': 'forDerivatives',
},
'inverse': undefined,
},
'future': {
'linear': undefined,
'inverse': undefined,
},
},
});
}
/**
* @method
* @name astros#fetchStatus
* @description the latest known information on the availability of the exchange API
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @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 = {}) {
const response = await this.publicGetInfoPing(params);
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": "pong",
// "sid": "1748419173585-001-f784"
// }
let status = this.safeString(response, 'data');
if (status === undefined) {
status = 'error';
}
else if (status === 'pong') {
status = 'ok';
}
else {
status = 'maintenance';
}
return {
'status': status,
'updated': undefined,
'eta': undefined,
'url': undefined,
'info': response,
};
}
/**
* @method
* @name astros#fetchMarkets
* @description retrieves data on all markets for astros
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @param {object} [params] extra parameters specific to the exchange api endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const response = await this.publicGetInfoPairs(params);
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": [
// {
// "id": 1,
// "tradeCoinId": 2,
// "tradeCoinName": "ETH",
// "tradeDecimal": 3,
// "priceDecimal": 2,
// "settleDecimal": 6,
// "settleCoinId": 4,
// "settleCoinName": "USD",
// "swapCoinId": 2,
// "swapCoinName": null,
// "symbol": "ETH-USD",
// "classifyId": null,
// "categoryId": null,
// "visible": 0,
// "tradable": true,
// "status": null,
// "sort": null,
// "isDual": false,
// "faceMultiplier": "1",
// "isDelivery": false,
// "deliveryTime": null,
// "deliveryMarketPrice": null,
// "deliveryStatus": null,
// "takerTradeFeeRate": "0.02",
// "makerTradeFeeRate": "0.015",
// "pair": "ETH-USD",
// "minCount": "0.01",
// "maxCount": "1000000",
// "brandExchange": null,
// "platform": null,
// "preMarket": null,
// "initMarkPrice": null,
// "releaseTime": null,
// "createTime": null
// }
// ],
// "sid": "1748419418733-001-5610"
// }
const rows = this.safeList(response, 'data', []);
return this.parseMarkets(rows);
}
/**
* @method
* @name astros#fetchLeverage
* @description fetch the set leverage for a market
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
*/
async fetchLeverage(symbol, params = {}) {
if (symbol === undefined) {
throw new ArgumentsRequired(this.id + ' fetchLeverage() requires a symbol argument');
}
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'contractPairId': market.id,
'timestamp': this.milliseconds(),
};
const response = await this.privateGetV1TradeGetUserLever(request);
//
// {
// "data": {
// {"contractPairId":"1","positionType":"3","lever":"10"}
// }
// }
//
const data = this.safeDict(response, 'data', null);
if (!data) {
return null;
}
let marginMode = '';
switch (data.positionType) {
case '3':
marginMode = 'isolated';
break;
case '4':
marginMode = 'cross';
break;
default:
marginMode = '';
}
return {
'info': data,
'symbol': symbol,
'marginMode': marginMode,
'longLeverage': Number(data.lever),
'shortLeverage': Number(data.lever),
};
}
/**
* @method
* @name astros#setLeverage
* @description set the level of leverage for a market
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @param {Int} leverage the rate of leverage
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.marginMode] required isolated | cross
* @returns {object} response from the exchange
*/
async setLeverage(leverage = undefined, symbol = undefined, params = {}) {
if (symbol === undefined) {
throw new ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
}
if (!leverage) {
throw new ArgumentsRequired(this.id + ' setLeverage() requires a leverage argument');
}
await this.loadMarkets();
const market = this.market(symbol);
const marginMode = params?.marginMode;
if (!marginMode || !['isolated', 'cross'].includes(marginMode)) {
throw new ArgumentsRequired(this.id + ' setLeverage() requires a marginMode argument');
}
const positionType = marginMode === 'isolated' ? 3 : 4;
const request = {
'contractPairId': market['id'],
'leverage': leverage,
'positionType': positionType,
'timestamp': this.milliseconds(),
};
const response = await this.setUserLever(request);
const isSuccess = this.safeDict(response, 'data', null);
return {
'status': isSuccess ? 'success' : 'failed',
};
}
parseMarket(market) {
// {
// "id": 1,
// "tradeCoinId": 2,
// "tradeCoinName": "ETH",
// "tradeDecimal": 3,
// "priceDecimal": 2,
// "settleDecimal": 6,
// "settleCoinId": 4,
// "settleCoinName": "USD",
// "swapCoinId": 2,
// "swapCoinName": null,
// "symbol": "ETH-USD",
// "classifyId": null,
// "categoryId": null,
// "visible": 0,
// "tradable": true,
// "status": null,
// "sort": null,
// "isDual": false,
// "faceMultiplier": "1",
// "isDelivery": false,
// "deliveryTime": null,
// "deliveryMarketPrice": null,
// "deliveryStatus": null,
// "takerTradeFeeRate": "0.02",
// "makerTradeFeeRate": "0.015",
// "pair": "ETH-USD",
// "minCount": "0.01",
// "maxCount": "1000000",
// "brandExchange": null,
// "platform": null,
// "preMarket": null,
// "initMarkPrice": null,
// "releaseTime": null,
// "createTime": null
// }
const marketId = this.safeString(market, 'id');
const marketType = 'swap';
const baseId = this.safeString(market, 'tradeCoinName');
const quoteId = this.safeString(market, 'settleCoinName');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settleId = this.safeString(market, 'settleCoinName');
const settle = this.safeCurrencyCode(settleId);
const symbol = base + '/' + quote + ':' + settle;
const status = this.safeBool(market, 'tradable');
let active = undefined;
if (status !== undefined) {
active = status;
}
return {
'id': marketId,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': marketType,
'spot': false,
'margin': false,
'swap': true,
'future': false,
'option': false,
'active': active,
'contract': true,
'linear': true,
'inverse': false,
'taker': this.safeNumber(market, 'takerTradeFeeRate'),
'maker': this.safeNumber(market, 'makerTradeFeeRate'),
'contractSize': this.parseNumber('1'),
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'settleDecimal'))),
'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'priceDecimal'))),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': this.safeNumber(market, 'minCount'),
'max': this.safeNumber(market, 'maxCount'),
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': undefined,
'max': undefined,
},
},
'created': this.safeInteger(market, 'createTime'),
'info': market,
};
}
/**
* @method
* @name astros#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the exchange server
*/
async fetchTime(params = {}) {
const response = await this.publicGetInfoTime(params);
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": 1714988294487,
// "sid": "1798295565880098817"
// }
return this.safeInteger(response, 'data');
}
/**
* @method
* @name astros#fetchOHLCV
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @see https://dex-aggregator-front-git-perp-navi-fd9a1df6.vercel.app/
* @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 {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
* @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);
const request = {
'pairName': market['info']['symbol'],
'period': this.safeString(this.timeframes, timeframe, timeframe),
};
if (limit !== undefined) {
request['limit'] = Math.min(limit, 1000);
}
const response = await this.publicGetInfoKline(this.extend(request, params));
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": [
// {
// "contractPairId": 1,
// "period": "15MIN",
// "time": 1748484900000,
// "open": "2709.24",
// "close": "2712.27",
// "low": "2708.45",
// "hight": "2713.09",
// "count": 11,
// "quantity": "9.554",
// "amount": "25917.27064"
// }
// ],
// "sid": "1748485042969-001-05f4"
// }
const rows = this.safeList(response, 'data', []);
return this.parseOHLCVs(rows, market, timeframe, since, limit);
}
parseOHLCV(ohlcv, market = undefined) {
// {
// "contractPairId": 1,
// "period": "15MIN",
// "time": 1748484900000,
// "open": "2709.24",
// "close": "2712.27",
// "low": "2708.45",
// "hight": "2713.09",
// "count": 11,
// "quantity": "9.554",
// "amount": "25917.27064"
// }
return [
this.safeInteger(ohlcv, 'time'),
this.safeNumber(ohlcv, 'open'),
this.safeNumber(ohlcv, 'hight'),
this.safeNumber(ohlcv, 'low'),
this.safeNumber(ohlcv, 'close'),
this.safeNumber(ohlcv, 'amount'),
];
}
/**
* @method
* @name astros#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://www.astros.com/docs/rest/futures-trading/market-data/get-part-order-book-level-2
* @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 = {
'pairName': market['info']['symbol'],
};
if (limit !== undefined) {
if ((limit === 20) || (limit === 100)) {
request['limit'] = limit;
}
else {
throw new BadRequest(this.id + ' fetchOrderBook() limit argument must be 20 or 100');
}
}
else {
request['limit'] = 20;
}
const response = await this.publicGetInfoDepth(this.extend(request, params));
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": {
// "bids": [
// {
// "price": "2731.48",
// "quantity": "12.383"
// },
// {
// "price": "2731.21",
// "quantity": "12.169"
// }
// ],
// "asks": [
// {
// "price": "2734.13",
// "quantity": "13.802"
// },
// {
// "price": "2734.33",
// "quantity": "11.364"
// }
// ]
// },
// "sid": "1748485574687-001-4f31"
// }
const timestamp = this.milliseconds(); // the exchange does not provide timestamp for this.
return this.parseOrderBook(this.safeDict(response, 'data', {}), market['symbol'], timestamp, 'bids', 'asks', 'price', 'quantity');
}
/**
* @method
* @name astros#fetchMarkPrice
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see https://www.astros.com/docs/rest/futures-trading/market-data/get-current-mark-price
* @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 fetchMarkPrice(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'pairName': market['info']['symbol'],
};
const response = await this.publicGetInfoMarkPrice(this.extend(request, params));
//
return this.parseTicker(response, market);
}
/**
* @method
* @name astros#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
* @see https://www.astros.com/docs/rest/futures-trading/market-data/get-symbols-list
* @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.method] the method to use, futuresPublicGetAllTickers or publicGetInfoPairs
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchTickers(symbols = undefined, params = {}) {
await this.loadMarkets();
symbols = this.marketSymbols(symbols);
[params] = this.handleOptionAndParams(params, 'fetchTickers', 'method', 'publicGetInfoPairs');
let response = undefined;
response = await this.publicGetInfoPairs(params);
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": [
// {
// "id": 1,
// "tradeCoinId": 2,
// "tradeCoinName": "ETH",
// "tradeDecimal": 3,
// "priceDecimal": 2,
// "settleDecimal": 6,
// "settleCoinId": 4,
// "settleCoinName": "USD",
// "swapCoinId": 2,
// "swapCoinName": null,
// "symbol": "ETH-USD",
// "classifyId": null,
// "categoryId": null,
// "visible": 0,
// "tradable": true,
// "status": null,
// "sort": null,
// "isDual": false,
// "faceMultiplier": "1",
// "isDelivery": false,
// "deliveryTime": null,
// "deliveryMarketPrice": null,
// "deliveryStatus": null,
// "takerTradeFeeRate": "0.02",
// "makerTradeFeeRate": "0",
// "pair": "ETH-USD",
// "minCount": "0.01",
// "maxCount": "1000000",
// "brandExchange": null,
// "platform": null,
// "preMarket": null,
// "initMarkPrice": null,
// "releaseTime": null,
// "createTime": null
// }
// ],
// "sid": "1833508475824193537"
// }
const data = this.safeList(response, 'data');
const tickers = this.parseTickers(data, symbols);
return this.filterByArrayTickers(tickers, 'symbol', symbols);
}
parseTicker(ticker, market = undefined) {
//
// from fetchMarkPrice
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": "2626.1085932222",
// "sid": "1833512508879224833"
// }
//
// from fetchTickers
//
// {
// "id": 2,
// "tradeCoinId": 1,
// "tradeCoinName": "BTC",
// "tradeDecimal": 3,
// "priceDecimal": 1,
// "settleDecimal": 6,
// "settleCoinId": 4,
// "settleCoinName": "USD",
// "swapCoinId": 1,
// "swapCoinName": null,
// "symbol": "BTC-USD",
// "classifyId": null,
// "categoryId": null,
// "visible": 0,
// "tradable": true,
// "status": null,
// "sort": null,
// "isDual": false,
// "faceMultiplier": "1",
// "isDelivery": false,
// "deliveryTime": null,
// "deliveryMarketPrice": null,
// "deliveryStatus": null,
// "takerTradeFeeRate": "0.02",
// "makerTradeFeeRate": "0",
// "pair": "BTC-USD",
// "minCount": "0.001",
// "maxCount": "1000000",
// "brandExchange": null,
// "platform": null,
// "preMarket": null,
// "initMarkPrice": null,
// "releaseTime": null,
// "createTime": null
// }
//
const marketId = this.safeString(ticker, 'id');
market = this.safeMarket(marketId, market);
const last = this.safeString2(ticker, 'price', 'lastTradePrice');
const timestamp = this.safeIntegerProduct(ticker, 'createTime', 0.000001);
return this.safeTicker({
'symbol': market['symbol'],
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'high': this.safeString(ticker, 'highPrice'),
'low': this.safeString(ticker, 'lowPrice'),
'bid': this.safeString(ticker, 'bestBidPrice'),
'bidVolume': this.safeString(ticker, 'bestBidSize'),
'ask': this.safeString(ticker, 'bestAskPrice'),
'askVolume': this.safeString(ticker, 'bestAskSize'),
'vwap': undefined,
'open': undefined,
'close': last,
'last': last,
'previousClose': undefined,
'change': this.safeString(ticker, 'priceChg'),
'percentage': this.safeString(ticker, 'priceChgPct'),
'average': undefined,
'baseVolume': this.safeString(ticker, 'volumeOf24h'),
'quoteVolume': this.safeString(ticker, 'turnoverOf24h'),
'markPrice': this.safeString2(ticker, 'markPrice', 'data'),
'indexPrice': this.safeString(ticker, 'indexPrice'),
'info': ticker,
}, market);
}
/**
* @method
* @name astros#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://www.astros.com/docs/rest/futures-trading/market-data/get-transaction-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 fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'pairName': market['info'].symbol,
};
if (limit !== undefined) {
request['limit'] = Math.min(limit, 1000);
}
const response = await this.publicGetInfoTrades(this.extend(request, params));
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": [
// {
// "contractMatchPairId": 4739473,
// "contractPairId": 2,
// "pair": null,
// "price": "106035.8",
// "quantity": "0.313",
// "amount": "33189.2054",
// "isLong": true,
// "time": "03:46:53",
// "timestamp": 1748576813000
// }
// ],
// "sid": "1833515680823721985"
// }
const trades = this.safeList(response, 'data', []);
return this.parseTrades(trades, market, since, limit);
}
parseTrade(trade, market = undefined) {
// fetchMyTrades
// {
// "id": 19862817,
// "entrustId": 180577696,
// "contractPositionId": 0,
// "contractPairId": 1,
// "createTime": "2024-09-09 07:08:26",
// "createTimeStamp": 1725865706000,
// "symbol": "ETH-USD",
// "accountCoinSymbol": null,
// "accountSettleDecimal": null,
// "lever": null,
// "isMarket": true,
// "isClose": false,
// "isLong": true,
// "isTaker": true,
// "averagePrice": "2315.09",
// "quantity": "0.02",
// "amount": "46.3018",
// "tradeFee": "0.027781",
// "positionFee": null,
// "profitLoss": "0",
// "isDelivery": null,
// "deliveryTime": null,
// "deliveryTimeStamp": null,
// "address": null,
// "openingPrice": null,
// "type": null,
// "restrictPrice": null
// }
//
// fetchTrades (public)
//
// {
// "contractMatchPairId": 4739473,
// "contractPairId": 2,
// "pair": null,
// "price": "106035.8",
// "quantity": "0.313",
// "amount": "33189.2054",
// "isLong": true,
// "time": "03:46:53",
// "timestamp": 1748576813000
// }
const marketId = this.safeString(trade, 'contractPairId');
market = this.safeMarket(marketId);
const id = this.safeString2(trade, 'contractMatchPairId', 'id');
const amountString = this.safeStringN(trade, ['size', 'quantity']);
const orderId = this.safeString(trade, 'entrustId');
const takerOrMaker = this.parseTakerOrMaker(this.safeBool(trade, 'isTaker'));
const timestamp = this.safeInteger2(trade, 'timestamp', 'createTimeStamp');
const typeRaw = this.safeInteger2(trade, 'type', 'orderType');
const type = this.parseOrderTypeForTrade(typeRaw);
const priceString = this.safeStringN(trade, ['price', 'dealPrice', 'averagePrice']);
return this.safeTrade({
'info': trade,
'id': id,
'order': orderId,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': market['symbol'],
'type': type,
'takerOrMaker': takerOrMaker,
'side': this.parseOrderSide(this.safeBool(trade, 'isLong')),
'price': priceString,
'amount': amountString,
'cost': this.safeString(trade, 'amount'),
'fee': {
'currency': undefined,
'cost': this.safeString(trade, 'tradeFee'),
'rate': undefined,
},
}, market);
}
parseSide(side) {
const sides = {
'SHORT': 'sell',
'LONG': 'buy',
};
return this.safeString(sides, side, side);
}
/**
* @method
* @name astros#fetchFundingRate
* @description fetch the current funding rate
* @see https://www.astros.com/docs/rest/futures-trading/funding-fees/get-current-funding-rate
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
*/
async fetchFundingRate(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'pairName': market['info'].symbol,
};
const response = await this.publicGetV1MarketFundingCurrent(this.extend(request, params));
//
// {
// "error": false,
// "code": 200,
// "msg": "SUCCESS",
// "data": {
// "symbol": "ETH-USD",
// "fundingRate": "-0.0000625"
// },
// "sid": "1811061846213328897"
// }
//
const data = this.safeDict(response, 'data', {});
// the website displayes the previous funding rate as "funding rate"
return this.parseFundingRate(data, market);
}
/**
* @method
* @name astros#fetchFundingInterval
* @description fetch the current funding rate interval
* @see https://www.astros.com/docs/rest/futures-trading/funding-fees/get-current-funding-rate
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
*/
async fetchFundingInterval(symbol, params = {}) {
return await this.fetchFundingRate(symbol, params);
}
parseFundingRate(data, market = undefined) {
//
// {
// "symbol": "ETH-USD",
// "fundingRate": "-0.0000625"
// }
//
const marketId = this.safeString(data, 'symbol');
return {
'info': data,
'symbol': this.safeSymbol(marketId, market, undefined, 'contract'),
'markPrice': undefined,
'indexPrice': undefined,
'interestRate': undefined,
'estimatedSettlePrice': undefined,
'timestamp': undefined,
'datetime': undefined,
'fundingRate': this.safeNumber(data, 'fundingRate'),
'fundingTimestamp': undefined,
'fundingDatetime': undefined,
'nextFundingRate': undefined,
'nextFundingTimestamp': undefined,
'nextFundingDatetime': undefined,
'previousFundingRate': undefined,
'previousFundingTimestamp': undefined,
'previousFundingDatetime': undefined,
'interval': undefined,
};
}
parseFundingInterval(interval) {
const intervals = {
'3600000': '1h',
'14400000': '4h',
'28800000': '8h',
'57600000': '16h',
'86400000': '24h',
};
return this.safeString(intervals, interval, interval);
}
/**
* @method
* @name astros#fetchFundingRateHistory
* @see https://www.astros.com/docs/rest/futures-trading/funding-fees/get-public-funding-history#request-url
* @description fetches historical funding rate prices
* @param {string} symbol unified symbol of the market to fetch the funding rate history for
* @param {int} [since] not used by kucuoinfutures
* @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.endTime] end time in ms (optional)
* @param {int} [params.idLe] requests the content on the page before this ID (older data, optional)
* @returns {object[]} a list of [funding rate structures]{@lin