const exchange = new ccxt.binance()console.log(exchange.features);// outputs like:{ spot: { sandbox: true, // whether testnet is supported createOrder: { triggerPrice: true, // if trigger order is supported triggerPriceType: undefined, // if trigger price type is supported (last, mark, index) triggerDirection: false, // if trigger direction is supported (ascending, descending) stopLossPrice: true, // if you can use createOrder to place a standalone stop-loss order (read "Stop Loss Orders" paragraph) takeProfitPrice: true, // ... similar as above stopLoss: { // if attached stopLoss can be sent together with an primary entry order triggerPriceType: { last: true, mark: true, index: true, }, price: true, // if 'limit' price is supported to be set (otherwise only market order would be supported) }, takeProfit : ..., // ... similar as above marginMode: true, // if `marginMode` param is supported (cross, isolated) timeInForce: { // supported TIF types GTC: true, IOC: true, FOK: true, PO: true, GTD: false }, hedged: false, // if `hedged` param is supported (true, false) leverage: false, // if `leverage` param is supported (true, false) selfTradePrevention: true, // if `selfTradePrevention` param is supported (true, false) trailing: true, // if trailing order is supported iceberg: true, // if iceberg order is supported marketBuyByCost: true, // if creating market buy order is possible with `cost` param marketBuyRequiresPrice: true,// if creating market buy order (if 'cost' not used) requires `price` param to be set }, createOrders: { 'max': 50, // if batch order creation is supported }, fetchMyTrades: { limit: 1000, // max limit per call daysBack: undefined, // max historical period that can be accessed untilDays: 1 // if `until` param is supported, then this is permitted distance from `since` }, fetchOrder: { marginMode: true, // when supported, margin order should be fetched with this flag trigger: false, // similar as above trailing: false // similar as above }, // other methods have similar properties fetchOpenOrders: { limit: undefined, marginMode: true, trigger: false, trailing: false }, fetchOrders: { limit: 1000, daysBack: undefined, untilDays: 10000, marginMode: true, trigger: false, trailing: false }, fetchClosedOrders: { limit: 1000, daysBackClosed: undefined, // max days-back for closed orders daysBackCanceled: undefined, // max days-back for canceled orders untilDays: 10000, marginMode: true, trigger: false, trailing: false }, fetchOHLCV: { paginate: true, limit: 1000 } }, swap: { linear: { ... }, // similar to above dict inverse: { ... }, // similar to above dict } future: { linear: { ... }, // similar to above dict inverse: { ... }, // similar to above dict }}
一些交易所还提供专用于测试目的的独立 API,允许开发者免费使用虚拟资金进行交易并验证自己的想法。这类 API 被称为 "测试网"、"沙盒"或"预发布环境"(使用虚拟测试资产),与使用真实资产的 "主网"和"生产环境" 相对应。沙盒 API 通常是生产 API 的克隆,即完全相同的 API,唯一的区别在于交易所服务器的 URL。
窗口算法(可选):如果用户提供 { 'rateLimiterAlgorithm': 'rollingWindow' } 选项,ccxt 将从漏桶模型切换到基于窗口的速率限制器(窗口大小可通过提供 rollingWindowSize: X0000 来自定义,CCXT 默认使用 60 秒作为窗口大小)。基于窗口的限制器在固定时间窗口内强制执行最大请求数(例如,每 X 毫秒最多 N 个请求)。一旦达到限制,后续请求将被延迟,直到当前窗口过期。
您可以使用 .enableRateLimit 属性开启/关闭内置速率限制器,如下所示:
// enable built-in rate limiting upon instantiation of the exchangeconst exchange = new ccxt.bitfinex ({ // 'enableRateLimit': true, // enabled by default})// or switch the built-in rate-limiter on or off later after instantiationexchange.enableRateLimit = true // enableexchange.enableRateLimit = false // disable
// DO NOT DO THIS!async function tick () { const exchange = new ccxt.binance () const response = await exchange.fetchOrderBook ('BTC/USDT') // ... some processing here ... return response}while (true) { const result = await tick () console.log (result)}
{ 'id': 'btc', // string literal for referencing within an exchange 'code': 'BTC', // uppercase unified string literal code of the currency 'name': 'Bitcoin', // string, human-readable name, if specified 'active': true, // boolean, currency status (tradeable and withdrawable) 'fee': 0.123, // withdrawal fee, flat 'precision': 8, // number of decimal digits "after the dot" (depends on exchange.precisionMode) 'deposit': true // boolean, deposits are available 'withdraw': true // boolean, withdraws are available 'limits': { // value limits when placing orders on this market 'amount': { 'min': 0.01, // order amount should be > min 'max': 1000, // order amount should be < max }, 'withdraw': { ... }, // withdrawal limits 'deposit': {...}, }, 'networks': {...} // network structures indexed by unified network identifiers (ERC20, TRC20, BSC, etc) 'info': { ... }, // the original unparsed currency info from the exchange}
{ 'id': 'tron', // string literal for referencing within an exchange 'network': 'TRC20' // unified network 'name': 'Tron Network', // string, human-readable name, if specified 'active': true, // boolean, currency status (tradeable and withdrawable) 'fee': 0.123, // withdrawal fee, flat 'precision': 8, // number of decimal digits "after the dot" (depends on exchange.precisionMode) 'deposit': true // boolean, deposits are available 'withdraw': true // boolean, withdraws are available 'limits': { // value limits when placing orders on this market 'amount': { 'min': 0.01, // order amount should be > min 'max': 1000, // order amount should be < max }, 'withdraw': { ... }, // withdrawal limits 'deposit': {...}, // deposit limits }, 'info': { ... }, // the original unparsed currency info from the exchange}
{ 'id': 'btcusd', // string literal for referencing within an exchange 'symbol': 'BTC/USD', // uppercase string literal of a pair of currencies 'base': 'BTC', // uppercase string, unified base currency code, 3 or more letters 'quote': 'USD', // uppercase string, unified quote currency code, 3 or more letters 'baseId': 'btc', // any string, exchange-specific base currency id 'quoteId': 'usd', // any string, exchange-specific quote currency id 'active': true, // boolean, market status 'type': 'spot', // spot for spot, future for expiry futures, swap for perpetual swaps, 'option' for options 'spot': true, // whether the market is a spot market 'margin': true, // whether the market is a margin market 'future': false, // whether the market is a expiring future 'swap': false, // whether the market is a perpetual swap 'option': false, // whether the market is an option contract 'contract': false, // whether the market is a future, a perpetual swap, or an option 'settle': 'USDT', // the unified currency code that the contract will settle in, only set if `contract` is true 'settleId': 'usdt', // the currencyId of that the contract will settle in, only set if `contract` is true 'contractSize': 1, // the size of one contract, only used if `contract` is true 'linear': true, // the contract is a linear contract (settled in quote currency) 'inverse': false, // the contract is an inverse contract (settled in base currency) 'expiry': 1641370465121, // the unix expiry timestamp in milliseconds, undefined for everything except market['type'] `future` 'expiryDatetime': '2022-03-26T00:00:00.000Z', // The datetime contract will in iso8601 format 'strike': 4000, // price at which a put or call option can be exercised 'optionType': 'call', // call or put string, call option represents an option with the right to buy and put an option with the right to sell // note, 'taker' and 'maker' compose extended data for markets, however it might be better to use `fetchTradingFees` for more accuracy 'taker': 0.002, // taker fee rate, 0.002 = 0.2% 'maker': 0.0016, // maker fee rate, 0.0016 = 0.16% 'percentage': true, // whether the taker and maker fee rate is a multiplier or a fixed flat amount 'tierBased': false, // whether the fee depends on your trading tier (your trading volume) 'feeSide': 'get', // string literal can be 'get', 'give', 'base', 'quote', 'other' 'precision': { // number of decimal digits "after the dot" 'price': 8, // integer or float for TICK_SIZE roundingMode, might be missing if not supplied by the exchange 'amount': 8, // integer, might be missing if not supplied by the exchange 'cost': 8, // integer, very few exchanges actually have it }, 'limits': { // value limits when placing orders on this market 'amount': { 'min': 0.01, // order amount should be > min 'max': 1000, // order amount should be < max }, 'price': { ... }, // same min/max limits for the price of the order 'cost': { ... }, // same limits for order cost = price * amount 'leverage': { ... }, // same min/max limits for the leverage of the order }, 'marginModes': { 'cross': false, // whether pair supports cross-margin trading 'isolated': false, // whether pair supports isolated-margin trading }, 'info': { ... }, // the original unparsed market info from the exchange}
每个市场都是一个关联数组(即字典),具有以下键:
id。交易所内市场或交易工具的字符串或数字 ID。市场 ID 在交易所内部用于在请求/响应过程中识别交易对。
在大多数情况下,您需要在访问其他 API 方法之前,先加载特定交易所的市场列表和交易符号。如果您忘记加载市场,ccxt 库将在您第一次调用统一 API 时自动加载。它将依次发送两个 HTTP 请求,第一个用于获取市场信息,第二个用于获取其他数据。因此,您第一次调用 fetchTicker、fetchBalance 等统一 CCXT API 方法时,将比后续调用耗费更多时间,因为它需要从交易所 API 加载更多的市场信息。详情请参阅速率限制器注意事项。
为优化内存使用并减少冗余 API 调用,您可以在同一交易所的多个实例之间共享市场数据。这在创建多个交易所实例或希望复用已加载市场数据时特别有用。
(async () => { // Create first exchange instance and load markets let exchange1 = new ccxt.binance() await exchange1.loadMarkets() // Create second exchange instance let exchange2 = new ccxt.binance() // Share markets from first instance to second using the setMarketsFromExchange method exchange2.setMarketsFromExchange(exchange1) // Now exchange2 can use the shared markets without loading them console.log(exchange2.symbols) // Available immediately // When calling loadMarkets on exchange2, it will use cached markets await exchange2.loadMarkets() // No API call, uses shared markets})()
市场共享的优势:
内存效率:多个交易所实例在内存中共享相同的市场对象
性能:消除了市场数据的冗余 API 调用
资源节约:减少网络请求和 API 速率限制消耗
持久性:即使单个交易所实例被销毁,市场数据仍然可用
简单赋值替代方案:
如果您倾向于直接属性赋值,也可以通过直接赋值 markets 属性来共享市场:
// Simple direct assignment (ensure both exchanges are of same type)exchange2.markets = exchange1.markets;exchange2.symbols = exchange1.symbols; // Also copy symbols for full functionality
(async () => { console.log (await exchange.loadMarkets ()) let btcusd1 = exchange.markets['BTC/USD'] // get market structure by symbol let btcusd2 = exchange.market ('BTC/USD') // same result in a slightly different way let btcusdId = exchange.marketId ('BTC/USD') // get market id by symbol let symbols = exchange.symbols // get an array of symbols let symbols2 = Object.keys (exchange.markets) // same as previous line console.log (exchange.id, symbols) // print all symbols let currencies = exchange.currencies // a dictionary of currencies let bitfinex = new ccxt.bitfinex () await bitfinex.loadMarkets () bitfinex.markets['BTC/USD'] // symbol → market (get market by symbol) bitfinex.markets_by_id['XRPBTC'][0] // id → market (get market by id) bitfinex.markets['BTC/USD']['id'] // symbol → id (get id by symbol) bitfinex.markets_by_id['XRPBTC'][0]['symbol'] // id → symbol (get symbol by id)}) ()
(async () => { let kraken = new ccxt.kraken ({ verbose: true }) // log HTTP requests await kraken.loadMarkets () // request markets console.log (kraken.id, kraken.markets) // output a full list of all loaded markets console.log (Object.keys (kraken.markets)) // output a short list of market symbols console.log (kraken.markets['BTC/USD']) // output single market details await kraken.loadMarkets () // return a locally cached version, no reload let reloadedMarkets = await kraken.loadMarkets (true) // force HTTP reload = true console.log (reloadedMarkets['ETH/BTC'])}) ()
# Pythonimport asyncioimport ccxt.async_support as ccxtasync def print_poloniex_ethbtc_ticker(): poloniex = ccxt.poloniex() print(await poloniex.fetch_ticker('ETH/BTC')) await polonix.close() # close the exchange instance when you don't need it anymoreasyncio.run(print_poloniex_ethbtc_ticker())
params = {'type':'margin', 'isIsolated': 'TRUE'} # --------------┑# params will go as the last argument to the unified method |# vbinance.create_order('BTC/USDT', 'limit', 'buy', amount, price, params)
请注意,统一 API 的大多数方法都接受一个可选的 params 参数。它是一个关联数组(字典,默认为空),包含您希望覆盖的参数。params 的内容因交易所而异,请查阅交易所的 API 文档以了解支持的字段和值。如需向统一查询传递自定义设置或可选参数,请使用 params 字典。
(async () => { const params = { 'foo': 'bar', // exchange-specific overrides in unified queries 'Hello': 'World!', // see their docs for more details on parameter names } // the overrides go into the last argument to the unified call ↓ HERE const result = await exchange.fetchOrderBook (symbol, length, params)}) ()
大多数统一方法将返回单个对象或对象的普通数组(列表)(成交记录、订单、交易记录等)。然而,几乎没有交易所会一次性返回所有订单、所有成交记录、所有 OHLCV K 线或所有交易记录。大多数情况下,其 API 会将输出限制在一定数量的最新对象内。您无法通过一次调用获取从历史开始到当前时刻的所有对象。实际上,几乎没有交易所会允许或容忍这种做法。
exchange.parse8601 ('2018-01-01T00:00:00Z') == 1514764800000 // integer in milliseconds, Z = UTCexchange.iso8601 (1514764800000) == '2018-01-01T00:00:00Z' // from milliseconds to iso8601 stringexchange.seconds () // integer UTC timestamp in secondsexchange.milliseconds () // integer UTC timestamp in milliseconds
这是目前整个 CCXT 统一 API 中使用的分页类型。用户提供一个毫秒(!)为单位的 since 时间戳以及用于限制结果数量的 limit 值。要逐页遍历感兴趣的对象,用户可执行以下操作(以下为伪代码,根据所涉及的交易所,可能需要覆盖某些交易所特定的参数):
if (exchange.has['fetchTrades']) { let since = exchange.milliseconds () - 86400000 // -1 day from now // alternatively, fetch from a certain starting datetime // let since = exchange.parse8601 ('2018-01-01T00:00:00Z') let allTrades = [] while (since < exchange.milliseconds ()) { const symbol = undefined // change for your symbol const limit = 20 // change for your limit const trades = await exchange.fetchTrades (symbol, since, limit) if (trades.length) { since = trades[trades.length - 1]['timestamp'] + 1 allTrades = allTrades.concat (trades) } else { break } }}
if (exchange.has['fetchTrades']) { let page = 0 // exchange-specific type and value let allTrades = [] while (true) { const symbol = undefined // change for your symbol const since = undefined const limit = 20 // change for your limit const params = { 'page': page, // exchange-specific non-unified parameter name } const trades = await exchange.fetchTrades (symbol, since, limit, params) if (trades.length) { // not thread-safe and exchange-specific! last_json_response = exchange.parseJson (exchange.last_http_response) page = last_json_response['cursor'] allTrades.push (trades) } else { break } }}
某些交易所可能通过订单ID对订单簿中的订单进行索引,在这种情况下,订单ID可能作为买/卖单的第三个元素返回:[ price, amount, id ]。这通常出现在没有聚合的L3订单簿中。订单簿中显示的订单 id 是指订单簿内的行ID,不一定对应交易所数据库中所有者或其他人可见的实际订单ID(不过,根据具体交易所,两者也可能相同)。
(async function test () { const ccxt = require ('ccxt') const exchange = new ccxt.bitfinex () const limit = 5 const orders = await exchange.fetchOrderBook ('BTC/USD', limit, { // this parameter is exchange-specific, all extra params have unique names per exchange 'group': 1, // 1 = orders are grouped by price, 0 = orders are separate })}) ()
// multiple tickersfetchTickers (symbols = undefined, params = {}) // for all tickers at once// for examplefetchTickers () // all symbolsfetchTickers ([ 'ETH/BTC', 'BTC/USDT' ]) // an array of specific symbols
{ 'symbol': string symbol of the market ('BTC/USD', 'ETH/BTC', ...) 'info': { the original non-modified unparsed reply from exchange API }, 'timestamp': int (64-bit Unix Timestamp in milliseconds since Epoch 1 Jan 1970) 'datetime': ISO8601 datetime string with milliseconds 'high': float, // highest price 'low': float, // lowest price 'bid': float, // current best bid (buy) price 'bidVolume': float, // current best bid (buy) amount (may be missing or undefined) 'ask': float, // current best ask (sell) price 'askVolume': float, // current best ask (sell) amount (may be missing or undefined) 'vwap': float, // volume weighed average price 'open': float, // opening price 'close': float, // price of last trade (closing price for current period) 'last': float, // same as `close`, duplicated for convenience 'previousClose': float, // closing price for the previous period 'change': float, // absolute change, `last - open` 'percentage': float, // relative change, `(change/open) * 100` 'average': float, // average price, `(last + open) / 2` 'baseVolume': float, // volume of base currency traded for last 24 hours 'quoteVolume': float, // volume of quote currency traded for last 24 hours}
if (exchange.has['fetchTicker']) { console.log (await (exchange.fetchTicker ('BTC/USD'))) // ticker for BTC/USD let symbols = Object.keys (exchange.markets) let random = Math.floor (Math.random () * (symbols.length - 1)) console.log (exchange.fetchTicker (symbols[random])) // ticker for a random symbol}
与统一 CCXT API 的大多数方法一样,fetchTickers 的最后一个参数是用于覆盖发送给交易所的请求参数的 params 参数。
返回值的结构如下:
{ 'info': { ... }, // the original JSON response from the exchange as is 'BTC/USD': { ... }, // a single ticker for BTC/USD 'ETH/BTC': { ... }, // a ticker for ETH/BTC ...}
从所有交易所(甚至没有相应 API 端点的交易所)获取所有行情的通用解决方案正在开发中,本节将很快更新。
与大多数其他统一和隐式方法一样,fetchOHLCV 方法接受一个关联数组(字典)作为最后一个参数,其中包含额外的 params,用于覆盖默认值,这些默认值会在向交易所发送请求时使用。params 的内容因交易所而异,请参阅交易所的 API 文档以了解支持的字段和值。
since 参数是一个整数 UTC 时间戳,以毫秒为单位(在整个库的所有统一方法中均如此)。
如果未指定 since,fetchOHLCV 方法将按照交易所本身的默认设置返回时间范围。这不是一个 bug。某些交易所将从时间起点返回蜡烛,其他交易所只返回最近的蜡烛,交易所的默认行为是预期行为。因此,不指定 since 时,返回的蜡烛范围将因交易所而异。应传入 since 参数以确保获取到精确所需的历史范围。
一阶原始数据由交易所 API 以近实时或尽可能接近实时的速度更新。二阶数据需要交易所花时间计算。例如,行情不过是订单簿和成交记录的滚动 24 小时统计切片。OHLCV 蜡烛和成交量也是从一阶成交数据计算得出的,代表特定时间段的固定统计切片。一小时内的成交量只是该小时内发生的相应成交记录的成交量之和。
显然,交易所需要一些时间来收集一阶数据并从中计算出二阶统计数据。这实际上意味着行情和 OHLCV 的更新始终慢于订单簿和成交记录。换句话说,在成交发生的时刻与交易所 API 更新或发布相应 OHLCV 蜡烛的时刻之间,交易所 API 中始终存在一定的延迟。
延迟(即交易所 API 计算二阶数据所需的时间)取决于交易所引擎的速度,因此因交易所而异。顶级交易所引擎通常能以极快的速度返回和更新最新的分钟级 OHLCV 蜡烛和行情。某些交易所可能按固定间隔更新,例如每秒一次或每隔几秒一次。速度较慢的交易所引擎可能需要几分钟才能更新二阶统计信息,其 API 返回当前最新 OHLCV 蜡烛时可能会延迟几分钟。
[ [ 1504541580000, // UTC timestamp in milliseconds, integer 4235.4, // (O)pen price, float 4240.6, // (H)ighest price, float 4230.0, // (L)owest price, float 4230.7, // (C)losing price, float 37.72941911 // (V)olume float (usually in terms of the base currency, the exchanges docstring may list whether quote or base units are used) ], ...]
if (exchange.has['fetchTrades']) { let sleep = (ms) => new Promise (resolve => setTimeout (resolve, ms)); for (symbol in exchange.markets) { console.log (await exchange.fetchTrades (symbol)) }}
[ { 'info': { ... }, // the original decoded JSON as is 'id': '12345-67890:09876/54321', // string trade id 'timestamp': 1502962946216, // Unix timestamp in milliseconds 'datetime': '2017-08-17 12:42:48.000', // ISO8601 datetime with milliseconds 'symbol': 'ETH/BTC', // symbol 'order': '12345-67890:09876/54321', // string order id or undefined/None/null 'type': 'limit', // order type, 'market', 'limit' or undefined/None/null 'side': 'buy', // direction of the trade, 'buy' or 'sell' 'takerOrMaker': 'taker', // string, 'taker' or 'maker' 'price': 0.06917684, // float price in quote currency 'amount': 1.5, // amount of base currency 'cost': 0.10376526, // total cost, `price * amount`, 'fee': { // if provided by exchange or calculated by ccxt 'cost': 0.0015, // float 'currency': 'ETH', // usually base currency for buys, quote currency for sells 'rate': 0.002, // the fee rate (if available) }, 'fees': [ // an array of fees if paid in multiple currencies { // if provided by exchange or calculated by ccxt 'cost': 0.0015, // float 'currency': 'ETH', // usually base currency for buys, quote currency for sells 'rate': 0.002, // the fee rate (if available) }, ] }, ...]
大多数交易所会为每笔交易返回上述大部分字段,但有些交易所不返回交易类型、方向、交易 ID 或订单 ID。大多数情况下,您可以保证获得每笔交易的时间戳、日期时间、交易对、价格和数量。
第二个可选参数 since 按时间戳筛选数组,第三个 limit 参数按返回项的数量(计数)筛选。
如果用户未指定 since,fetchTrades 方法将返回交易所默认范围内的公开交易。默认集合因交易所而异,有些交易所将返回从该交易对上市之日起的交易,其他交易所将返回一组较少的交易(例如最近 24 小时、最近 100 笔交易等)。如果用户需要精确控制时间范围,用户有责任指定 since 参数。
大多数统一方法将返回单个对象或对象的普通数组(列表)(交易)。然而,几乎没有交易所(如果有的话)会一次性返回所有交易。大多数情况下,其 API 将输出限制为一定数量的最近对象。您无法在一次调用中获取从创世至今的所有对象。实际上,很少有交易所会容忍或允许这种情况。
要获取历史交易,用户需要分批或按"页"遍历数据。分页通常意味着在循环中*"逐一获取部分数据"*。
在大多数情况下,用户需要使用至少某种类型的分页才能一致地获得预期结果。
另一方面,某些交易所根本不支持公开交易的分页。通常,交易所只提供最新的交易。
fetchTrades () / fetch_trades() 方法还接受可选的 params(关联键数组/字典,默认为空)作为其第四个参数。您可以使用它将额外参数传递给方法调用,或覆盖特定的默认值(在交易所支持的情况下)。有关详细信息,请参阅您的交易所的 API 文档。
{ 'status': 'ok', // 'ok', 'shutdown', 'error', 'maintenance' 'updated': undefined, // integer, last updated timestamp in milliseconds if updated via the API 'eta': undefined, // when the maintenance or outage is expected to end 'url': undefined, // a link to a GitHub issue or to an exchange post on the subject}
{ symbol: 'BTC/USDT', // Unified market symbol base: 'BTC', // Unified currency code of the base currency baseRate: 0.00025, // A decimal value rate that interest is accrued at quote: 'USDT', // Unified currency code of the quote currency quoteRate: 0.00025, // A decimal value rate that interest is accrued at period: 86400000, // The amount of time in milliseconds that is required to accrue the interest amount specified by rate timestamp: 1646956800000, // Timestamp for when the currency had this rate datetime: '2022-03-11T00:00:00.000Z', // Datetime for when the currency had this rate info: [ ... ]}
{ currency: 'USDT', // Unified currency code rate: 0.0006, // A ratio of the rate that interest is accrued at period: 86400000, // The amount of time in milliseconds that is required to accrue the interest amount specified by rate timestamp: 1646956800000, // Timestamp for when the currency had this rate datetime: '2022-03-11T00:00:00.000Z', // Datetime for when the currency had this rate info: [ ... ]}
[ { "tier": 1, // tier index "symbol": "BTC/USDT", // the market symbol that the leverage tier applies to "currency": "USDT", // the currency that minNotional and maxNotional are in "minNotional": 0, // the lowest amount of this tier // stake = 0.0 "maxNotional": 10000, // the highest amount of this tier // max stake amount at 75x leverage = 133.33333333333334 "maintenanceMarginRate": 0.0065, // maintenance margin rate "maxLeverage": 75, // max available leverage for this market when the value of the trade is > minNotional and < maxNotional "info": { ... } // Response from exchange }, { "tier": 2, "symbol": "BTC/USDT", "currency": "USDT", "minNotional": 10000, // min stake amount at 50x leverage = 200.0 "maxNotional": 50000, // max stake amount at 50x leverage = 1000.0 "maintenanceMarginRate": 0.01, "maxLeverage": 50, "info": { ... }, }, ... { "tier": 9, "symbol": "BTC/USDT", "currency": "USDT", "minNotional": 20000000, "maxNotional": 50000000, "maintenanceMarginRate": 0.5, "maxLeverage": 1, "info": { ... }, },]
[ { 'info': { ... }, // the original decoded JSON as is 'symbol': 'BTC/USDT:USDT-231006-25000-P', // unified CCXT market symbol 'contracts': 2, // the number of derivative contracts 'contractSize': 0.001, // the contract size for the trading pair 'price': 27038.64, // the average liquidation price in the quote currency 'baseValue': 0.002, // value in the base currency (contracts * contractSize) 'quoteValue': 54.07728, // value in the quote currency ((contracts * contractSize) * price) 'timestamp': 1696996782210, // Unix timestamp in milliseconds 'datetime': '2023-10-11 03:59:42.000', // ISO8601 datetime with milliseconds }, ...]
params(Dictionary)特定于交易所 API 端点的额外参数(例如 {"category": "options"})
// for example
fetchAllGreeks () // all symbols
fetchAllGreeks ([ 'BTC/USD:BTC-240927-40000-C', 'ETH/USD:ETH-240927-4000-C' ]) // an array of specific symbols
{ 'symbol': 'BTC/USD:BTC-240927-40000-C', // unified CCXT market symbol 'timestamp': 1699593511632, // unix timestamp in milliseconds 'datetime': '2023-11-10T05:18:31.632Z', // ISO8601 datetime with milliseconds 'delta': 0.59833, // measures the rate of change in the options price per $1 change in the underlying assets price 'gamma': 0.00002, // measures the rate of change in the delta per $1 change in the underlying assets price 'theta': -13.4441, // measures the dollar amount that an options price will decline per day 'vega': 142.30124, // measures the dollar amount that an options price changes with a 1% change in the implied volatility 'rho': 131.82621, // measures the dollar amount that an options price changes with a 1% change in interest rates 'vanna': 0.06671, // measures the amount that an options delta changes with a 1% change in implied volatility 'volga': 925.95015, // measures the amount that an options vega changes with a 1% change in implied volatility 'charm': 0.18433, // measures the amount that an options delta changes each day until expiration 'bidSize': 2.2, // the options bid amount 'askSize': 9, // the options ask amount 'bidImpliedVolatility': 60.06, // the expected percentage price change of the underlying asset, over the remaining life of the option, calculated using the bid price 'askImpliedVolatility': 61.85, // the expected percentage price change of the underlying asset, over the remaining life of the option, calculated using the ask price 'markImpliedVolatility': 60.86, // the expected percentage price change of the underlying asset, over the remaining life of the option, calculated using the mark price 'bidPrice': 0.214, // the bid price of the option 'askPrice': 0.2205, // the ask price of the option 'markPrice': 0.2169, // the mark price of the option 'lastPrice': 0.215, // the last price of the option 'underlyingPrice': 39165.86, // the current market price of the underlying asset 'info': { ... }, // the original decoded JSON as is}
{ 'info': { ... }, // the original decoded JSON as is 'currency': 'BTC', // unified CCXT currency code 'symbol': 'BTC/USD:BTC-240927-40000-C', // unified CCXT market symbol 'timestamp': 1699593511632, // unix timestamp in milliseconds 'datetime': '2023-11-10T05:18:31.632Z', // ISO8601 datetime with milliseconds 'impliedVolatility': 60.06, // the expected percentage price change of the underlying asset, over the remaining life of the option 'openInterest': 10, // the number of open options contracts that have not been settled 'bidPrice': 0.214, // the bid price of the option 'askPrice': 0.2205, // the ask price of the option 'midPrice': 0.2205, // the price in between the bid and the ask 'markPrice': 0.2169, // the mark price of the option 'lastPrice': 0.215, // the last price of the option 'underlyingPrice': 39165.86, // the current market price of the underlying asset 'change': 15.43, // the 24 hour price change in a dollar amount 'percentage': 11.86, // the 24 hour price change as a percentage 'baseVolume': 100.86, // the volume in units of the base currency 'quoteVolume': 23772.86, // the volume in units of the quote currency}
{ 'info': { ... }, // the original decoded JSON as is 'symbol': 'BTC/USDT:USDT', // unified CCXT market symbol 'rank': 5, // a quantile rank from 1 to 5 with 5 being the highest risk 'rating': 'high', // a string risk rating as either low, medium or high 'percent': 72.86, // the risk percentage with a higher percentage being a higher risk of auto de leverage 'timestamp': 1699593511632, // unix timestamp in milliseconds 'datetime': '2023-11-10T05:18:31.632Z', // ISO8601 datetime with milliseconds}
- this part of the unified API is currenty a work in progress- there may be some issues and missing implementations here and there- contributions, pull requests and feedback appreciated
请注意,这些方法的命名表明该方法返回单个订单还是多个订单(订单数组/列表)。fetchOrder() 方法需要一个必填的订单 ID 参数(字符串)。某些交易所还需要通过交易对来通过 ID 获取订单,因为订单 ID 可能与各种交易对相交。另外,请注意上述所有其他方法都返回一个数组(列表)的订单。它们中的大多数也需要 symbol 参数,但某些交易所允许在未指定 symbol 的情况下查询(即所有交易对)。
如果用户调用交易所不支持或 ccxt 未实现的方法,库将抛出 NotSupported 异常。
要检查上述任何方法是否可用,请查看交易所的 .has 属性:
'use strict';const ccxt = require ('ccxt')const id = 'poloniex'exchange = new ccxt[id] ()console.log (exchange.has)
.has 属性的典型结构通常包含以下与订单查询 API 方法对应的标志:
exchange.has = { // ... other flags ... 'fetchOrder': true, // available from the exchange directly and implemented in ccxt 'fetchOrders': false, // not available from the exchange or not implemented in ccxt 'fetchOpenOrders': true, 'fetchClosedOrders': 'emulated', // not available from the exchange, but emulated in ccxt // ... other flags ...}
布尔值 true 和 false 的含义显而易见。字符串值 emulated 表示交易所 API 中缺少该特定方法,ccxt 将在客户端尽可能进行变通处理。
如果用户未指定 since,fetchTrades()/fetchOrders() 方法将返回交易所的默认结果集。默认结果集因交易所而异,部分交易所会返回从该交易对上市之日起的交易或最近订单,另一些交易所则返回较少的交易或订单(例如最近24小时、最近100笔交易、前100个订单等)。如果用户需要精确控制时间范围,则需自行指定 since 参数。
注意:并非所有交易所都提供按起始时间筛选交易和订单列表的功能,因此对 since 和 limit 的支持因交易所而异。不过,大多数交易所确实提供了至少一种"分页"或"滚动"的替代方案,可以通过额外的 params 参数进行覆盖。
要通过订单 ID 获取特定订单的详细信息,请使用 fetchOrder() / fetch_order() 方法。部分交易所即使在按 ID 获取特定订单时也需要提供交易对符号。
fetchOrder/fetch_order 方法的签名如下:
if (exchange.has['fetchOrder']) { // you can use the params argument for custom overrides let order = await exchange.fetchOrder (id, symbol = undefined, params = {})}
部分交易所没有按 ID 获取订单的端点,ccxt 会在可能的情况下进行模拟。 目前此功能在某些地方可能仍有缺失,因为这项工作仍在进行中。
您可以在额外的 params 参数中传入自定义的键值对,以指定特定的订单类型或其他所需设置。
以下是使用 fetchOrder 方法从已认证的交易所实例获取订单信息的示例:
(async function () { const order = await exchange.fetchOrder (id) console.log (order)}) ()
{ 'id': '12345-67890:09876/54321', // string 'clientOrderId': 'abcdef-ghijklmnop-qrstuvwxyz', // a user-defined clientOrderId, if any 'datetime': '2017-08-17 12:42:48.000', // ISO8601 datetime of 'timestamp' with milliseconds 'timestamp': 1502962946216, // order placing/opening Unix timestamp in milliseconds 'lastTradeTimestamp': 1502962956216, // Unix timestamp of the most recent trade on this order 'status': 'open', // 'open', 'closed', 'canceled', 'expired', 'rejected' 'symbol': 'ETH/BTC', // symbol 'type': 'limit', // 'market', 'limit' 'timeInForce': 'GTC', // 'GTC', 'IOC', 'FOK', 'PO' 'side': 'buy', // 'buy', 'sell' 'price': 0.06917684, // float price in quote currency (may be empty for market orders) 'average': 0.06917684, // float average filling price 'amount': 1.5, // ordered amount of base currency 'filled': 1.1, // filled amount of base currency 'remaining': 0.4, // remaining amount to fill 'cost': 0.076094524, // 'filled' * 'price' (filling price used where available) 'trades': [ ... ], // a list of order trades/executions 'fee': { // fee info, if available 'currency': 'BTC', // which currency the fee is (usually quote) 'cost': 0.0009, // the fee amount in that currency 'rate': 0.002, // the fee rate (if available) }, 'triggerPrice': 10000, // price that will be the order trigger 'stopLossPrice': 50000, 'takeProfitPrice': 150000, 'reduceOnly': false, 'postOnly': false, 'info': { ... }, // the original unparsed order structure as is}
订单的 status 通常为 'open'(未成交或部分成交)、'closed'(完全成交)或 'canceled'(未成交后取消,或部分成交后取消)。
部分交易所允许用户在下新订单时指定过期时间戳。如果订单在该时间前未成交,其 status 将变为 'expired'。
await exchange.loadMarkets()symbol = 'BTC/USDT:USDT'market = exchange.market(symbol)print(market['contractSize'])# Let's say you want to convert 0.5 BTC to the number of contracts:number_contracts = round((0.5 * 1) / market['contractSize'])
// camelCaseNotationexchange.createMarketSellOrder (symbol, amount, params)exchange.createMarketBuyOrder (symbol, amount, params)// underscore_notationexchange.create_market_sell_order (symbol, amount, params)exchange.create_market_buy_order (symbol, amount, params)// using general createMarketOrder and side = 'buy' or 'sell'exchange.createMarketOrder (symbol, side, amount, params)exchange.create_market_order (symbol, side, amount, params)// using general createOrder, type = 'market' and side = 'buy' or 'sell'exchange.createOrder (symbol, 'market', side, amount, ...)exchange.create_order (symbol, 'market', side, amount, ...)
// this example is oversimplified and doesn't show all the code that is// required to handle the errors and exchange metadata properly// it shows just the concept of placing a market buy orderconst exchange = new ccxt.cex ({ 'apiKey': YOUR_API_KEY, 'secret': 'YOUR_SECRET', // 'options': { // 'createMarketBuyOrderRequiresPrice': true, // default // },});(async () => { // when `createMarketBuyOrderRequiresPrice` is true, we can pass the price // so that the total cost of the order would be calculated inside the library // by multiplying the amount over price (amount * price) const symbol = 'BTC/USD' const amount = 2 // BTC const price = 9000 // USD // cost = amount * price = 2 * 9000 = 18000 (USD) // note that we don't use createMarketBuyOrder here, instead we use createOrder // createMarketBuyOrder will omit the price and will not work when // exchange.options['createMarketBuyOrderRequiresPrice'] = true const order = await exchange.createOrder (symbol, 'market', 'buy', amount, price) console.log (order)}) ()
const exchange = new ccxt.cex ({ 'apiKey': YOUR_API_KEY, 'secret': 'YOUR_SECRET', 'options': { 'createMarketBuyOrderRequiresPrice': false, // switch off },})// or, to switch it off later, after the exchange instantiation, you can doexchange.options['createMarketBuyOrderRequiresPrice'] = false;(async () => { // when `createMarketBuyOrderRequiresPrice` is true, we can pass the price // so that the total cost of the order would be calculated inside the library // by multiplying the amount over price (amount * price) const symbol = 'BTC/USD' const amount = 2 // BTC const price = 9000 // USD cost = amount * price // ← instead of the amount cost goes ↓ here const order = await exchange.createMarketBuyOrder (symbol, cost) console.log (order)}) ()
| price | amount----|---------------- | 1500 | 200 | 1400 | 300 a | 1300 | 100 s | 1200 | 200 k | 1100 | 300 | 1000 | 100 <--- you bought to enter a long position here at 1000 | 900 | 100----|---------------- last price is 900 | 800 | 100 | 700 | 200 <------- you place a stop loss order here at 700 <----------------------+ b | 600 | 100 when your stopLossPrice is reached from above | i | 500 | 300 it will close your position at market price below 700 ----------------+ d | 400 | 200 <- or it will be executed at your limit price lower that stopLossPrice -+ | 300 | 100 | 200 | 100
| price | amount----|---------------- | 1500 | 200 | 1400 | 300 <------------------------------------------------------------------------+ a | 1300 | 100 <------ you place a stop loss order here at 1300 <---------------------+ | s | 1200 | 200 when your stopLossPrice is reached from below | | k | 1100 | 300 it will close your position at market price above 1300 --------------+ | | 1000 | 100 or it will be executed at your limit price higher than stopLossPrice -+ | 900 | 100----|---------------- last price is 900 (you sold at 700) | 800 | 100 | 700 | 200 <--- you sold to enter a short position here at 700 b | 600 | 100 i | 500 | 300 d | 400 | 200 | 300 | 100 | 200 | 100
止损单在以下情况下被激活,当标的资产/合约价格:
从上方跌破 stopLossPrice,适用于卖单。(例如:平多仓,避免进一步亏损)
从下方涨破 stopLossPrice,适用于买单。(例如:平空仓,避免进一步亏损)
// for a stop loss orderconst params = { 'stopLossPrice': 55.45, // your stop loss price}const order = await exchange.createOrder (symbol, type, side, amount, price, params)
| price | amount----|---------------- | 1500 | 200 | 1400 | 300 <------------------------------------------------------------------------------+ a | 1300 | 100 <--- it will close your position at market price above 1300 | s | 1200 | 200 when your takeProfitPrice is reached from below | k | 1100 | 300 or it will be executed at your limit price higher than your takeProfitPrice -+ | 1000 | 100 <- you bought to enter a long position here at 1000 | 900 | 100----|---------------- last price is 900 | 800 | 100 | 700 | 200 b | 600 | 100 i | 500 | 300 d | 400 | 200 | 300 | 100 | 200 | 100
| price | amount----|---------------- | 1500 | 200 | 1400 | 300 a | 1300 | 100 s | 1200 | 200 k | 1100 | 300 | 1000 | 100 | 900 | 100----|---------------- last price is 900 (you sold at 700) | 800 | 100 | 700 | 200 <--- you sold to enter a short position here at 700 b | 600 | 100 <------ you place a take profit order here at 600 i | 500 | 300 when your takeProfitPrice is reached from above d | 400 | 200 it will be close your position at market price below 600 | 300 | 100 <- or it will be executed at your limit price lower than your takeProfitPrice | 200 | 100
止盈单在以下情况下被激活,当标的资产价格:
从下方涨破 takeProfitPrice,适用于卖单。(例如:以盈利平多仓)
从上方跌破 takeProfitPrice,适用于买单。(例如:以盈利平空仓)
// for a take profit orderconst params = { 'takeProfitPrice': 120.45, // your take profit price}const order = await exchange.createOrder (symbol, type, side, amount, price, params)
exchange.featureValue('BTC/USDT', 'createOrder', 'stopLoss') // if stopLoss supportedexchange.featureValue('BTC/USDT', 'createOrder', 'stopLoss.price') // if limit price is supported for stoploss
const params = { 'stopLoss': { 'triggerPrice': 12.34, // at what price it will trigger 'price': 12.00, // if exchange supports, 'price' param would be limit price (for market orders, don't include this param) }, 'takeProfit': { // similar params here }}const order = await exchange.createOrder ('SOL/USDT', 'limit', 'buy', 0.5, 13, params)
symbol = 'BTC/USDT:USDT';type = 'market';side = 'sell';amount = 1.0;price = undefined;const params = { 'trailingPercent': 1.0, // percentage away from the current market price 1.0 is equal to 1% // 'trailingAmount': 100.0, // quote amount away from the current market price // 'trailingTriggerPrice': 44500.0, // the price to trigger activating a trailing stop order // 'reduceOnly': true, // set to true if you want to close a position, set to false if you want to open a new position}const order = await exchange.createOrder (symbol, type, side, amount, price, params)
- this part of the unified API is currenty a work in progress- there may be some issues and missing implementations here and there- contributions, pull requests and feedback appreciated
- this part of the unified API is currenty a work in progress- there may be some issues and missing implementations here and there- contributions, pull requests and feedback appreciated
在许多情况下,交易所的 API 需要提供 symbol 参数,因此您必须遍历所有交易对才能获取所有成交记录。如果缺少 symbol 且交易所需要它,则 CCXT 将抛出 ArgumentsRequired 异常以向用户发出需求信号。然后必须指定 symbol。其中一种方法是通过查看非零余额以及交易记录(提款和存款)从所有交易对列表中筛选相关交易对。此外,交易所将对您可以追溯多久有时间限制。
{ 'info': { ... }, // the original decoded JSON as is 'id': '12345-67890:09876/54321', // string trade id 'timestamp': 1502962946216, // Unix timestamp in milliseconds 'datetime': '2017-08-17 12:42:48.000', // ISO8601 datetime with milliseconds 'symbol': 'ETH/BTC', // symbol 'order': '12345-67890:09876/54321', // string order id or undefined/None/null 'type': 'limit', // order type, 'market', 'limit' or undefined/None/null 'side': 'buy', // direction of the trade, 'buy' or 'sell' 'takerOrMaker': 'taker', // string, 'taker' or 'maker' 'price': 0.06917684, // float price in quote currency 'amount': 1.5, // amount of base currency 'cost': 0.10376526, // total cost, `price * amount`, 'fee': { // provided by exchange or calculated by ccxt 'cost': 0.0015, // float 'currency': 'ETH', // usually base currency for buys, quote currency for sells 'rate': 0.002, // the fee rate (if available) }, 'fees': [ // an array of fees if paid in multiple currencies { // if provided by exchange or calculated by ccxt 'cost': 0.0015, // float 'currency': 'ETH', // usually base currency for buys, quote currency for sells 'rate': 0.002, // the fee rate (if available) }, ],}
{ 'id': 'hqfl-f125f9l2c9', // string id of the ledger entry, e.g. an order id 'direction': 'out', // or 'in' 'account': '06d4ab58-dfcd-468a', // string id of the account if any 'referenceId': 'bf7a-d4441fb3fd31', // string id of the trade, transaction, etc... 'referenceAccount': '3146-4286-bb71', // string id of the opposite account (if any) 'type': 'trade', // string, reference type, see below 'currency': 'BTC', // string, unified currency code, 'ETH', 'USDT'... 'amount': 123.45, // absolute number, float (does not include the fee) 'timestamp': 1544582941735, // milliseconds since epoch time in UTC 'datetime': "2018-12-12T02:49:01.735Z", // string of timestamp, ISO8601 'before': 0, // amount of currency on balance before 'after': 0, // amount of currency on balance after 'status': 'ok', // 'ok, 'pending', 'canceled' 'fee': { // object or undefined 'cost': 54.321, // absolute number on top of the amount 'currency': 'ETH', // string, unified currency code, 'ETH', 'USDT'... }, 'info': { ... }, // raw ledger entry as is from the exchange}
从 fetchDepositMethodId、fetchDepositMethodIds 返回的存款 ID 结构如下所示:
{ 'info': {}, // raw unparsed data as returned from the exchange 'id': '75ab52ff-f25t', // the deposit id 'currency': 'USD', // fiat currency 'verified': true, // whether funding through this id is verified or not 'tag': 'from credit card', // tag / memo / name of funding source}
可以使用以下方式检索账户存款数据
fetchDeposit () 获取单笔存款
fetchDeposits ( code ) 获取同一货币的多笔存款
fetchDeposits () 获取账户的所有存款
fetchDeposit (id, code = undefined, params = {})
参数
id (String) 必填 存款 ID
code (String) 统一 CCXT 货币代码,必填(例如 "USDT")
params (Dictionary) 特定于交易所 API 端点的参数(例如 {"network": "TRX"})
{ 'info': { ... }, // the JSON response from the exchange as is 'id': '123456', // exchange-specific transaction id, string 'txid': '0x68bfb29821c50ca35ef3762f887fd3211e4405aba1a94e448a4f218b850358f0', 'timestamp': 1534081184515, // timestamp in milliseconds 'datetime': '2018-08-12T13:39:44.515Z', // ISO8601 string of the timestamp 'addressFrom': '0x38b1F8644ED1Dbd5DcAedb3610301Bf5fa640D6f', // sender 'address': '0x02b0a9b7b4cDe774af0f8e47cb4f1c2ccdEa0806', // "from" or "to" 'addressTo': '0x304C68D441EF7EB0E2c056E836E8293BD28F8129', // receiver 'tagFrom', '0xabcdef', // "tag" or "memo" or "payment_id" associated with the sender 'tag': '0xabcdef' // "tag" or "memo" or "payment_id" associated with the address 'tagTo': '0xhijgklmn', // "tag" or "memo" or "payment_id" associated with the receiver 'type': 'deposit', // 'withdrawal' or 'transfer', string 'amount': 1.2345, // float (does not include the fee) 'currency': 'ETH', // a common unified currency code, string 'status': 'pending', // 'ok', 'failed', 'canceled', string 'updated': undefined, // UTC timestamp of most recent status change in ms 'comment': 'a comment or message defined by the user if any', 'fee': { // the entire fee structure may be undefined 'currency': 'ETH', // a unified fee currency code 'cost': 0.1234, // float 'rate': undefined, // approximately, fee['cost'] / amount, float },}
{ 'info': response, // raw unparsed data as returned from the exchange 'currency': 'USDC', // currency code 'network': 'ERC20', // a deposit/withdraw networks, ERC20, TRC20, BSC20 (see below) 'address': '0x', // blockchain address in terms of the requested currency and network 'tag': undefined, // tag / memo / paymentId for particular currencies (XRP, XMR, ...)}
对于某些货币,如 AEON、BTS、GXS、NXT、SBD、STEEM、STR、XEM、XLM、XMR、XRP,交易所通常需要额外的 tag 参数。其他货币的 tag 将设为 undefined / None / null。tag 是附加在提现交易上的备忘录、消息或支付 ID,对于这些货币是强制性的,用于标识接收方用户账户。
指定 tag 和 address 时请务必谨慎。tag不是您可以随意定义的字符串!您不能在 tag 中发送用户消息和评论。tag 字段的目的是正确寻址您的钱包,因此必须准确无误。您只能使用从您所用交易所获取的 tag,否则您的交易可能永远无法到达目的地。
{ info: { ... } // Unparsed exchange response symbol: 'BTC/USDT', // The market that the interest was accrued in currency: 'USDT', // The currency of the interest interest: 0.00004842, // The amount of interest that was charged interestRate: 0.0002, // The borrow interest rate amountBorrowed: 5.81, // The amount of currency that was borrowed marginMode: 'cross', // The margin mode of the borrowed amount timestamp: 1648699200000, // The timestamp that the interest was charged datetime: '2022-03-31T04:00:00.000Z', // The datetime that the interest was charged}
{ id: '1234323', // integer, the transaction id currency: 'USDT', // string, the currency that is borrowed or repaid amount: 5.81, // float, the amount of currency that was borrowed or repaid symbol: 'BTC/USDT:USDT', // string, unified market symbol timestamp: 1648699200000, // integer, the timestamp of when the transaction was made datetime: '2022-03-31T04:00:00.000Z', // string, the datetime of when the transaction was made info: { ... } // Unparsed exchange response}
{ info: { ... }, type: 'add', // 'add', 'reduce', 'set' amount: 1, // amount added, reduced, or set total: 2, // total margin or undefined if not specified by the exchange code: 'USDT', symbol: 'XRP/USDT:USDT', status: 'ok'}
{ "info": { ... } // response from the exchange "symbol": "BTC/USDT:USDT", // unified market symbol "marginMode": "cross", // the margin mode either cross or isolated}
{ "info": { ... } // response from the exchange "symbol": "BTC/USDT:USDT", // unified market symbol "marginMode": "cross", // the margin mode either cross or isolated "longLeverage": 100, // the set leverage for a long position "shortLeverage": 75, // the set leverage for a short position}
{ 'info': { ... }, // json response returned from the exchange as is 'id': '1234323', // string, position id to reference the position, similar to an order id 'symbol': 'BTC/USD', // uppercase string literal of a pair of currencies 'timestamp': 1607723554607, // integer unix time since 1st Jan 1970 in milliseconds 'datetime': '2020-12-11T21:52:34.607Z', // ISO8601 representation of the unix time above 'isolated': true, // boolean, whether or not the position is isolated, as opposed to cross where margin is added automatically 'hedged': false, // boolean, whether or not the position is hedged, i.e. if trading in the opposite direction will close this position or make a new one 'side': 'long', // string, long or short 'contracts': 5, // float, number of contracts bought, aka the amount or size of the position 'contractSize': 100, // float, the size of one contract in quote units 'entryPrice': 20000, // float, the average entry price of the position 'markPrice': 20050, // float, a price that is used for funding calculations 'notional': 100000, // float, the value of the position in the settlement currency 'leverage': 100, // float, the leverage of the position, related to how many contracts you can buy with a given amount of collateral 'collateral': 5300, // float, the maximum amount of collateral that can be lost, affected by pnl 'initialMargin': 5000, // float, the amount of collateral that is locked up in this position 'maintenanceMargin': 1000, // float, the mininum amount of collateral needed to avoid being liquidated 'initialMarginPercentage': 0.05, // float, the initialMargin as a percentage of the notional 'maintenanceMarginPercentage': 0.01, // float, the maintenanceMargin as a percentage of the notional 'unrealizedPnl': 300, // float, the difference between the market price and the entry price times the number of contracts, can be negative 'liquidationPrice': 19850, // float, the price at which collateral becomes less than maintenanceMargin 'marginMode': 'cross', // string, can be cross or isolated 'percentage': 3.32, // float, represents unrealizedPnl / initialMargin * 100}
{ 'info': { ... }, // the original decoded JSON as is 'symbol': 'BTC/USDT:USDT', // unified CCXT market symbol 'rank': 5, // a quantile rank from 1 to 5 with 5 being the highest risk 'rating': 'high', // a string risk rating as either low, medium or high 'percent': 72.86, // the risk percentage with a higher percentage being a higher risk of auto de leverage 'timestamp': 1699593511632, // unix timestamp in milliseconds 'datetime': '2023-11-10T05:18:31.632Z', // ISO8601 datetime with milliseconds}
Go 用户注意: 设置任何代理属性后,必须调用 UpdateProxySettings() 以应用更改:
exchange := ccxt.NewBinance(nil)exchange.ProxyUrl = "http://your-proxy-url:8080"exchange.UpdateProxySettings() // Required in Go to apply proxy settings
CORS(即跨源资源共享)主要影响浏览器,是常见警告 No 'Access-Control-Allow-Origin' header is present on the requested resource 的根本原因。当脚本(在浏览器中运行)向第三方域发起请求时就会出现此问题(默认情况下此类请求会被阻止,除非目标域明确允许)。
因此,在这种情况下,您需要通过一个"CORS"代理进行通信,该代理会将请求(而非直接的浏览器端请求)重定向到目标交易所。要设置 CORS 代理,您可以运行sample-local-proxy-server-with-cors示例文件,并在 ccxt 中设置 .proxyUrl 属性,将请求路由到 cors/proxy 服务器。
// try to call a unified methodtry { const response = await exchange.fetchTicker ('ETH/BTC') console.log (response)} catch (e) { // if the exception is thrown, it is "caught" and can be handled here // the handling reaction depends on the type of the exception // and on the purpose or business logic of your application if (e instanceof ccxt.NetworkError) { console.log (exchange.id, 'fetchTicker failed due to a network error:', e.message) // retry or whatever } else if (e instanceof ccxt.ExchangeError) { console.log (exchange.id, 'fetchTicker failed due to exchange error:', e.message) // retry or whatever } else { console.log (exchange.id, 'fetchTicker failed with:', e.message) // retry or whatever }}
exchange.options['maxRetriesOnFailure'] = 3 # if we get an error like the ones mentioned above we will retry up to three times per requestexchange.options['maxRetriesOnFailureDelay'] = 1000 # we will wait 1000ms (1s) between retries
class BaseError extends Error { constructor () { super () // a workaround to make `instanceof BaseError` work in ES5 this.constructor = BaseError this.__proto__ = BaseError.prototype }}
"Timestamp for this request is outside of the recvWindow."
"Invalid request, please check your server timestamp or recv_window param."
"Timestamp for this request was 1000ms ahead of the server's time."
exchange = ccxt.binance()exchange.load_markets()exchange.verbose = True # for less noise, you can set that after `load_markets`, but if the error happens during `load_markets` then place this line before it# ... your codes here ...