CCXT

Manual do CCXT Pro

CCXT Pro é uma parte gratuita do CCXT que adiciona suporte a streaming via WebSocket: https://github.com/ccxt/ccxt/issues/15171

Manual

CCXT Pro é uma parte gratuita do CCXT que adiciona suporte a streaming via WebSocket: https://github.com/ccxt/ccxt/issues/15171

A pilha do CCXT Pro é construída sobre o CCXT e estende as classes principais do CCXT, usando:

  • Mixins em nível de protótipo JavaScript
  • Herança múltipla em Python
  • Traits em PHP
  • Herança de classe em Java (as classes de exchange pro estendem as classes de exchange base)

O CCXT Pro depende fortemente do transpilador do CCXT para suporte a múltiplos idiomas.

                                 User

    +-------------------------------------------------------------+
    |                          CCXT Pro                           |
    +------------------------------+------------------------------+
    |            Public            .           Private            |
    +=============================================================+
    │                              .                              |
    │                  The Unified CCXT Pro API                   |
    |                              .                              |
    |     loadMarkets              .         watchBalance         |
    |     watchTicker              .         watchOrders          |
    |     watchTickers             .         watchMyTrades        |
    |     watchOrderBook           .         watchPositions       |
    |     watchOHLCV               .         createOrderWs        |
    |     watchStatus              .         editOrderWs          |
    |     watchTrades              .         cancelOrderWs        |
    │     watchOHLCVForSymbols     .         cancelOrdersWs       |
    │     watchTradesForSymbols    .         cancelAllOrdersWs    |
    │     watchOrderBookForSymbols .                              |
    │                              .                              |
    +=============================================================+
    │                          unWatch                            |
    │                   (to stop **watch** method)                |
    +=============================================================+
    │                              .                              |
    |            The Underlying Exchange-Specific APIs            |
    |         (Derived Classes And Their Implementations)         |
    │                              .                              |
    +=============================================================+
    │                              .                              |
    |                 CCXT Pro Base Exchange Class                |
    │                              .                              |
    +=============================================================+

    +-------------------------------------------------------------+
    |                                                             |
    |                            CCXT                             |
    |                                                             |
    +=============================================================+

Exchanges

A biblioteca CCXT Pro suporta atualmente os seguintes 74 mercados de criptomoedas e APIs de negociação via WebSocket:
logoidnamevertypecertifiedpro
aftermathaftermathAftermathFinanceAPI Version 1DEX - Distributed EXchangeCCXT Pro
alpacaalpacaAlpacaAPI Version *CEX – Centralized EXchangeCCXT Pro
apexapexApexAPI Version 3DEX - Distributed EXchangeCCXT Pro
arkhamarkhamARKHAMAPI Version 1CEX – Centralized EXchangeCCXT Pro
ascendexascendexAscendEXAPI Version 2CEX – Centralized EXchangeCCXT Pro
asterasterAsterAPI Version 1DEX - Distributed EXchangeCCXT Pro
backpackbackpackBackpackAPI Version 1CEX – Centralized EXchangeCCXT Pro
bequantbequantBequantAPI Version 3CEX – Centralized EXchangeCCXT Pro
binancebinanceBinanceAPI Version *CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
binancecoinmbinancecoinmBinance COIN-MAPI Version *CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
binanceusbinanceusBinance USAPI Version *CEX – Centralized EXchangeCCXT Pro
binanceusdmbinanceusdmBinance USDⓈ-MAPI Version *CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bingxbingxBingXAPI Version 1CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bitfinexbitfinexBitfinexAPI Version 2CEX – Centralized EXchangeCCXT Pro
bitgetbitgetBitgetAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bithumbbithumbBithumbAPI Version *CEX – Centralized EXchangeCCXT Pro
bitmartbitmartBitMartAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bitmexbitmexBitMEXAPI Version 1CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bitoprobitoproBitoProAPI Version 3CEX – Centralized EXchangeCCXT Pro
bitruebitrueBitrueAPI Version 1CEX – Centralized EXchangeCCXT Pro
bitstampbitstampBitstampAPI Version 2CEX – Centralized EXchangeCCXT Pro
bittradebittradeBitTradeAPI Version 1CEX – Centralized EXchangeCCXT Pro
bitvavobitvavoBitvavoAPI Version 2CEX – Centralized EXchangeCCXT Pro
blockchaincomblockchaincomBlockchain.comAPI Version 3CEX – Centralized EXchangeCCXT Pro
blofinblofinBloFinAPI Version 1CEX – Centralized EXchangeCCXT Pro
bullishbullishBullishAPI Version 3CEX – Centralized EXchangeCCXT Pro
bybitbybitBybitAPI Version 5CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
bybiteubybiteuBybit EUAPI Version 5CEX – Centralized EXchangeCCXT Pro
bydfibydfiBYDFiAPI Version 1CEX – Centralized EXchangeCCXT Pro
cexcexCEX.IOAPI Version *CEX – Centralized EXchangeCCXT Pro
coinbasecoinbaseCoinbase AdvancedAPI Version 2CEX – Centralized EXchangeCCXT Pro
coinbaseexchangecoinbaseexchangeCoinbase ExchangeAPI Version *CEX – Centralized EXchangeCCXT Pro
coinbaseinternationalcoinbaseinternationalCoinbase InternationalAPI Version 1CEX – Centralized EXchangeCCXT Pro
coinexcoinexCoinExAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
cryptocomcryptocomCrypto.comAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
deepcoindeepcoinDeepCoinAPI Version 1CEX – Centralized EXchangeCCXT Pro
deribitderibitDeribitAPI Version 2CEX – Centralized EXchangeCCXT Pro
derivederivederiveAPI Version 1DEX - Distributed EXchangeCCXT Pro
dydxdydxdYdXAPI Version 4DEX - Distributed EXchangeCCXT Pro
gategateGateAPI Version 4CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
geminigeminiGeminiAPI Version 1CEX – Centralized EXchangeCCXT Pro
grvtgrvtGRVTAPI Version 1DEX - Distributed EXchangeCCXT Pro
hashkeyhashkeyHashKey GlobalAPI Version 1CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
hollaexhollaexHollaExAPI Version 2CEX – Centralized EXchangeCCXT Pro
htxhtxHTXAPI Version 1CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
hyperliquidhyperliquidHyperliquidAPI Version 1DEX - Distributed EXchangeCCXT CertifiedCCXT Pro
independentreserveindependentreserveIndependent ReserveAPI Version *CEX – Centralized EXchangeCCXT Pro
krakenkrakenKrakenAPI Version 0CEX – Centralized EXchangeCCXT Pro
krakenfutureskrakenfuturesKraken FuturesAPI Version 3CEX – Centralized EXchangeCCXT Pro
kucoinkucoinKuCoinAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
kucoinfutureskucoinfuturesKuCoin FuturesAPI Version 2CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
lbanklbankLBankAPI Version 2CEX – Centralized EXchangeCCXT Pro
lighterlighterLighterAPI Version 1DEX - Distributed EXchangeCCXT Pro
lunolunolunoAPI Version 1CEX – Centralized EXchangeCCXT Pro
mexcmexcMEXC GlobalAPI Version 3CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
modetrademodetradeMode TradeAPI Version 1DEX - Distributed EXchangeCCXT Pro
myokxmyokxMyOKX (EEA)API Version 5CEX – Centralized EXchangeCCXT Pro
ndaxndaxNDAXAPI Version *CEX – Centralized EXchangeCCXT Pro
okxokxOKXAPI Version 5CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
okxusokxusOKX (US)API Version 5CEX – Centralized EXchangeCCXT Pro
onetradingonetradingOne TradingAPI Version 1CEX – Centralized EXchangeCCXT Pro
oxfunoxfunOXFUNAPI Version 3CEX – Centralized EXchangeCCXT Pro
p2bp2bp2bAPI Version 2CEX – Centralized EXchangeCCXT Pro
pacificapacificaPacificaAPI Version 1DEX - Distributed EXchangeCCXT Pro
paradexparadexParadexAPI Version 1DEX - Distributed EXchangeCCXT Pro
phemexphemexPhemexAPI Version 1CEX – Centralized EXchangeCCXT Pro
poloniexpoloniexPoloniexAPI Version *CEX – Centralized EXchangeCCXT Pro
toobittoobitToobitAPI Version 1CEX – Centralized EXchangeCCXT Pro
upbitupbitUpbitAPI Version 1CEX – Centralized EXchangeCCXT Pro
weexweexWeexAPI Version 3CEX – Centralized EXchangeCCXT Pro
whitebitwhitebitWhiteBitAPI Version 4CEX – Centralized EXchangeCCXT Pro
woowooWOO XAPI Version 1CEX – Centralized EXchangeCCXT CertifiedCCXT Pro
woofiprowoofiproWOOFI PROAPI Version 1DEX - Distributed EXchangeCCXT CertifiedCCXT Pro
xtxtXTAPI Version 4CEX – Centralized EXchangeCCXT Pro

Esta é a lista de exchanges no CCXT Pro com suporte a APIs WebSockets. Esta lista será atualizada com novas exchanges regularmente.

Lista completa de exchanges disponíveis no CCXT via REST: Mercados de Exchange de Criptomoedas Suportados.

Utilização

- this part of the doc is under heavy development right now
- there may be some typos, mistakes and missing info here and there
- contributions, pull requests and feedback appreciated

Pré-requisitos

A melhor forma de compreender o CCXT Pro é garantir que você domina todo o Manual do CCXT e pratica o CCXT padrão primeiro. O CCXT Pro se apoia no CCXT. As duas bibliotecas compartilham muitas características em comum, incluindo:

  • os conceitos de API pública e API privada autenticada
  • mercados, símbolos, códigos de moeda e ids
  • estruturas e formatos de dados unificados, livros de ordens, negociações, ordens, velas, timeframes, ...
  • exceções e mapeamentos de erros
  • autenticação e chaves de API (para feeds e chamadas privadas)
  • opções de configuração

O público do CCXT Pro é composto principalmente por traders algorítmicos profissionais e desenvolvedores. Para trabalhar de forma eficiente com esta biblioteca, o utilizador deve estar bem familiarizado com os conceitos de streaming. É necessário compreender as diferenças subjacentes entre APIs de streaming baseadas em conexão (WebSocket, CCXT Pro) e APIs baseadas em requisição-resposta (REST, CCXT).

O fluxo geral de estilo assíncrono para uma aplicação CCXT é o seguinte:


// a RESTful orderbook polling request-response loop

while (condition) {

    try {

        // fetch some of the public data
        orderbook = await exchange.fetchOrderBook (symbol, limit)

        // do something or react somehow based on that data
        // ...

    } catch (e) {

        // handle errors
    }
}

No CCXT Pro, cada método RESTful unificado público e privado com prefixo fetch* também possui um método correspondente baseado em stream com prefixo watch*, como segue:

  • API Pública
    • fetchStatuswatchStatus
    • fetchOrderBookwatchOrderBook
    • fetchOrderBookForSymbolswatchOrderBookForSymbols
    • fetchTickerwatchTicker
    • fetchTickerswatchTickers
    • fetchOHLCVwatchOHLCV
    • fetchOHLCVForSymbolswatchOHLCVForSymbols
    • fetchTradeswatchTrades
    • fetchTradesForSymbolswatchTradesForSymbols
    • fetchBidsAskswatchBidsAsks
    • fetchLiquidationswatchLiquidations
    • fetchLiquidationsForSymbolswatchLiquidationsForSymbols
  • API Privada
    • fetchBalancewatchBalance
    • fetchOrderswatchOrders
    • fetchOrdersForSymbolswatchOrdersForSymbols
    • fetchMyTradeswatchMyTrades
    • fetchPositionwatchPosition
    • fetchPositionswatchPositions
    • fetchLiquidationswatchLiquidations
    • fetchMyLiquidationswatchMyLiquidations
    • fetchMyLiquidationsForSymbolswatchMyLiquidationsForSymbols
    • fetchFundingRateswatchFundingRates
  • Alternativas REST
    • fetchTradesfetchTradesWs
    • createOrdercreateOrderWs
    • editOrdereditOrderWs
    • cancelOrdercancelOrderWs
    • cancelOrderscancelOrdersWs
    • cancelAllOrderscancelAllOrdersWs
    • etc ...
  • unWatch (interrompe a subscrição em segundo plano para os métodos watch)
    • unWatchOrderBook
    • unWatchOrderBooksForSymbols
    • unWatchTrades
    • unWatchTradesForSymbols
    • unWatchOHLCVForSymbols
    • unWatchOrderBookForSymbols
    • unWatchPositions
    • unWatchTickers
    • unWatchMyTrades
    • unWatchTicker
    • unWatchOHLCV
    • unWatchOrders

A API de Streaming Unificada do CCXT Pro herda os padrões de uso do CCXT para facilitar a migração.

O fluxo geral de estilo assíncrono para uma aplicação CCXT Pro (em oposição a uma aplicação CCXT acima) é apresentado abaixo:


// a stream-based (WebSocket) orderbook feed loop

while (condition) {

    try {

        // watch some of the public data
        orderbook = await exchange.watchOrderBook (symbol, limit)

        // do something or react somehow based on that data
        // ...

    } catch (e) {

        // handle errors
    }
}

Esse padrão de uso normalmente é encapsulado em um método de lógica de negócio central chamado "função tick()", uma vez que reitera uma reação aos eventos recebidos (também conhecidos como ticks). Pelos dois exemplos acima, fica evidente que o padrão de uso genérico no CCXT Pro e no CCXT é idêntico.

Muitas das regras e conceitos do CCXT também se aplicam ao CCXT Pro:

  • O CCXT Pro carregará mercados e os armazenará em cache na primeira chamada a um método de API unificada
  • O CCXT Pro chamará métodos RESTful do CCXT internamente, se necessário
  • O CCXT Pro lançará exceções padrão do CCXT quando necessário
  • ...

Especificidades do Streaming

Apesar das numerosas características em comum, as APIs baseadas em streaming possuem suas próprias especificidades, devido à sua natureza orientada a conexão.

Ter uma interface baseada em conexão implica mecanismos de gestão de conexão. As conexões são gerenciadas pelo CCXT Pro de forma transparente para o utilizador. Cada instância de exchange gerencia seu próprio conjunto de conexões.

Na sua primeira chamada a qualquer método watch*(), a biblioteca estabelecerá uma conexão com um stream/recurso específico da exchange e a manterá. Se a conexão já existir, ela será reutilizada. A biblioteca tratará as sequências de mensagens de requisição/resposta de subscrição, bem como a autenticação/assinatura caso o stream solicitado seja privado.

A biblioteca também monitorará o estado do uplink e manterá a conexão ativa. Diante de uma exceção crítica, desconexão ou timeout/falha de conexão, a próxima iteração da função tick chamará o método watch, que acionará uma reconexão. Desta forma, a biblioteca trata as desconexões e reconexões para o utilizador de forma transparente. O CCXT Pro aplica os limites de taxa necessários e atrasos de reconexão com backoff exponencial. Toda essa funcionalidade está habilitada por padrão e pode ser configurada através das propriedades da exchange, como de costume.

A maioria das exchanges possui apenas uma URL base para APIs de streaming (geralmente WebSocket, iniciando com ws:// ou wss://). Algumas podem ter mais de uma URL para cada stream, dependendo do feed em questão.

As APIs de Streaming das exchanges podem ser classificadas em duas categorias diferentes:

  • sub ou subscribe permite apenas receber
  • pub ou publish permite enviar e receber

Sub

Uma interface sub geralmente permite subscrever a um stream de dados e escutá-lo. A maioria das exchanges que suportam WebSockets oferecerá apenas uma API do tipo sub. O tipo sub inclui o streaming de dados públicos de mercado. Às vezes, as exchanges também permitem subscrever dados privados do utilizador. Após o utilizador subscrever a um feed de dados, o canal começa a funcionar de forma unidirecional, enviando atualizações da exchange para o utilizador continuamente.

Tipos comuns de streams de dados públicos:

  • livro de ordens (mais comum) - atualizações sobre ordens adicionadas, editadas e eliminadas (também conhecidas como deltas de mudança)
  • atualizações de ticker com mudança das estatísticas de 24 horas
  • feed de execuções (também comum) - um stream ao vivo de negociações públicas
  • feed de velas ohlcv
  • heartbeat
  • chat/trollbox da exchange

Tipos menos comuns de streams de dados privados do utilizador:

  • o stream de negociações privadas do utilizador
  • atualizações de ordens ao vivo
  • atualizações de saldo
  • streams personalizados
  • streams específicos da exchange e outros

Pub

Uma interface pub geralmente permite que os utilizadores enviem requisições de dados para o servidor. Isso normalmente inclui ações comuns do utilizador, como:

  • colocação de ordens
  • cancelamento de ordens
  • colocação de requisições de saque
  • publicação de mensagens no chat/trollbox
  • etc

Algumas exchanges não oferecem uma API WS do tipo pub, oferecendo apenas a API WS do tipo sub. No entanto, existem exchanges que possuem uma API de Streaming completa. Na maioria dos casos, um utilizador não consegue operar de forma eficaz apenas com a API de Streaming. As exchanges farão streaming de dados públicos de mercado via sub, e a API REST ainda é necessária para a parte pub quando ausente.

unWatch

Cada método watchX estabelece uma subscrição com um stream e continuará recebendo atualizações da exchange. Mesmo que você pare de obter o valor de retorno do método watchX, o stream continuará enviando dados, que são tratados e armazenados em segundo plano. Para interromper essas subscrições em segundo plano, você deve usar o método unWatch (ex.: watchTrades -> unWatchTrades).

Estruturas de Dados Incrementais

Em muitos casos, devido à natureza unidirecional dos feeds de dados subjacentes, a aplicação que escuta no lado do cliente precisa manter um snapshot local dos dados na memória e mesclar as atualizações recebidas do servidor da exchange no snapshot local. As atualizações provenientes da exchange também são frequentemente chamadas de deltas, porque na maioria dos casos essas atualizações conterão apenas as mudanças entre dois estados dos dados e não incluirão os dados que não mudaram, tornando necessário armazenar o estado atual S em cache local de todos os objetos de dados relevantes.

Toda essa funcionalidade é tratada pelo CCXT Pro para o utilizador. Para trabalhar com o CCXT Pro, o utilizador não precisa rastrear ou gerenciar subscrições e dados relacionados. O CCXT Pro manterá um cache de estruturas na memória para lidar com a complexidade subjacente.

Cada atualização recebida indica quais partes dos dados mudaram, e o lado receptor "incrementa" o estado local S mesclando a atualização sobre o estado atual S, movendo para o próximo estado local S'. Em termos de CCXT Pro, isso é chamado de "estado incremental" e as estruturas envolvidas no processo de armazenamento e atualização do estado em cache são chamadas de "estruturas incrementais". O CCXT Pro introduz várias novas classes base para tratar o estado incremental quando necessário.

As estruturas incrementais retornadas pelos métodos unificados do CCXT Pro são geralmente de um dos dois tipos:

  1. Objeto decodificado em JSON (object em JavaScript, dict em Python, array() em PHP). Este tipo pode ser retornado por métodos públicos e privados como watchOrderBook, watchTicker, watchBalance, watchOrder, etc.
  2. Um array/lista de objetos (geralmente ordenados em ordem cronológica). Este tipo pode ser retornado por métodos como watchOHLCV, watchTrades, watchMyTrades, watchOrders, etc.

Os métodos unificados que retornam arrays como watchOHLCV, watchTrades, watchMyTrades, watchOrders, são baseados na camada de cache. O utilizador precisa compreender o funcionamento interno da camada de cache para trabalhar com ela de forma eficiente.

O cache é uma deque de tamanho fixo, também conhecida como array/lista com duas extremidades. A biblioteca CCXT Pro tem um limite razoável no número de objetos armazenados na memória. Por padrão, as estruturas de array em cache armazenarão até 1000 entradas de cada tipo (1000 negociações mais recentes, 1000 velas mais recentes, 1000 ordens mais recentes). O número máximo permitido pode ser configurado pelo utilizador na instanciação ou posteriormente:

ccxtpro.binance({
    'options': {
        'tradesLimit': 1000,
        'OHLCVLimit': 1000,
        'ordersLimit': 1000,
    },
})

# or

exchange.options['tradesLimit'] = 1000
exchange.options['OHLCVLimit'] = 1000
exchange.options['ordersLimit'] = 1000

Os limites do cache devem ser definidos antes de chamar qualquer método watch e não podem ser alterados durante a execução do programa.

Quando há espaço disponível no cache, novos elementos são simplesmente adicionados ao final. Se não houver espaço suficiente para um novo elemento, o elemento mais antigo é excluído do início do cache para liberar espaço. Assim, por exemplo, o cache cresce de 0 até 1000 negociações mais recentes e depois permanece no máximo de 1000 negociações mais recentes, renovando constantemente os dados armazenados a cada nova atualização recebida da exchange. Isso lembra uma janela deslizante ou uma porta deslizante, que se parece com o mostrado abaixo:

      past > ------------------ > time > - - - - - - - - > future


                           sliding frame
                           of 1000 most
                           recent trades
                        +-----------------+
                        |                 |
                        |===========+=====|
+----------------+------|           |     | - - - - - + - - - - - - - - + - - -
|                |      |           |     |           |                 |
0              1000     |         2000    |         3000              4000  ...
|                |      |           |     |           |                 |
+----------------+------|           |     | - - - - - + - - - - - - - - + - - -
                        |===========+=====|
                        |                 |
                        +---+---------+---+
                            |         |
                      since ^         ^ limit

                   date-based pagination arguments
                         are always applied
                       within the cached frame

O utilizador pode configurar os limites do cache usando exchange.options conforme mostrado acima. Não confunda os limites do cache com o limite de paginação.

Observe que os parâmetros since e limit de paginação baseada em data têm um significado diferente e são sempre aplicados dentro da janela em cache! Se o utilizador especificar um argumento since na chamada watchTrades(), o CCXT Pro retornará todas as negociações em cache com timestamp >= since. Se o utilizador não especificar um argumento since, o CCXT Pro retornará as negociações em cache desde o início da janela deslizante. Se o utilizador especificar um argumento limit, a biblioteca retornará até limit velas a partir de since ou desde o início do cache. Por essa razão, o utilizador não pode paginar além do frame em cache devido às especificidades do WebSocket em tempo real.

exchange.options['tradesLimit'] = 5  # set the size of the cache to 5

# this call will return up to 5 cached trades
await exchange.watchTrades (symbol)

# the following call will return the first 2 of up to 5 cached trades
await exchange.watchTrades (symbol, since=None, limit=2)

# this call will first filter cached trades by trade['timestamp'] >= since
# and will return the first 2 of up to 5 cached trades that pass the filter
since = exchange.iso8601('2020-01-01T00:00:00Z')
limit = 2
await exchange.watchTrades (symbol, since, limit)

Modo newUpdates

Se você quiser sempre obter apenas a negociação mais recente, deve instanciar a exchange com o sinalizador newUpdates definido como true.

exchange = ccxtpro.binance({'newUpdates': True})
while True:
    trades = await exchange.watchTrades (symbol)
    print(trades)

O modo newUpdates continua a utilizar o cache deslizante em segundo plano, mas o usuário receberá apenas as novas atualizações. Isso ocorre porque algumas exchanges usam estruturas incrementais, portanto precisamos manter um cache de objetos, já que a exchange pode fornecer apenas informações parciais, como atualizações de status.

O resultado do modo newUpdates será uma ou mais atualizações ocorridas desde a última vez que exchange.watchMethod foi resolvido. O CCXT Pro pode retornar uma ou mais ordens que foram atualizadas desde a chamada anterior. O resultado de chamar exchange.watchOrders será como mostrado abaixo:

[
    order, // see /docs/manual#order-structure
    order,
    order,
    ...
]

Aviso de Depreciação: no futuro, newUpdates: true será o modo padrão e você precisará definir newUpdates como false para obter o cache deslizante.

const ccxtpro = require ('ccxt').pro
console.log ('CCXT version', ccxtpro.version)
console.log ('Supported exchanges:', ccxtpro.exchanges)

O módulo CCXT Pro importado envolve o CCXT dentro de si mesmo – toda exchange instanciada via CCXT Pro possui todos os métodos do CCXT, bem como a funcionalidade adicional.

Instanciação

O CCXT Pro foi projetado para a sintaxe async/await e depende fortemente de primitivos assíncronos como promises e futures.

Criar uma instância de exchange no CCXT Pro é praticamente idêntico a criar uma instância de exchange no CCXT.

const ccxt = require ('ccxt').pro
const exchange = new ccxtpro.binance ({ newUpdates: false })

Python

A implementação Python do CCXT Pro depende do asyncio integrado e, em particular, do Event Loop. Em Python é possível fornecer uma instância do event loop do asyncio nos argumentos do construtor, como mostrado abaixo (idêntico ao ccxt.async support):

import ccxt.pro as ccxtpro
from asyncio import run

async def main():
    exchange = ccxtpro.kraken({'newUpdates': False})
    while True:
        orderbook = await exchange.watch_order_book('BTC/USD')
        print(orderbook['asks'][0], orderbook['bids'][0])
    await exchange.close()


run(main())

PHP

Em PHP, os primitivos assíncronos são emprestados do ReactPHP. A implementação PHP do CCXT Pro depende do Promise e do EventLoop em particular. Em PHP, o usuário é obrigado a fornecer uma instância do event loop do ReactPHP nos argumentos do construtor, como mostrado abaixo:

error_reporting(E_ALL);
date_default_timezone_set('UTC');
require_once 'vendor/autoload.php';

$exchange = new \ccxt\pro\kucoin(array( 'newUpdates' => false ));
using ccxt.pro;

    public async static Task Watch()
    {
        var exchange = new binance();
        while (true)
        {
            var trades = await exchange.WatchTrades("BTC/USDT");
            Console.WriteLine("Trades: " + JsonConvert.SerializeObject(trades, Formatting.Indented));
        }
    }

Propriedades da Exchange

Toda instância do CCXT Pro contém todas as propriedades da instância CCXT subjacente. Além das propriedades padrão do CCXT, a instância do CCXT Pro inclui o seguinte:

{
    'has': { // an associative array of extended exchange capabilities
        'ws': true, // only available in CCXT Pro
        'watchOrderBook': true,
        'watchTicker': true,
        'watchTickers': true,
        'watchTrades': true,
        'watchMyTrades': true,
        'watchOHLCV': true,
        'watchBalance': true,
        'watchPositions': true,
        'createOrderWs': true,
        'editOrderWs': true,
        'cancelOrderWs': true,
        'cancelOrdersWs': false,
        'cancelAllOrdersWs': true,
        'fetchOrderWs': true,
        'fetchOrdersWs': true,
        'fetchBalanceWs': true,
        'fetchMyTradesWs': true,
        ...
    },
    'urls': {
        'api': { // will contain a streaming API base URL, depending on the underlying protocol
            'ws': 'wss://ws.exchange.com',            // https://en.wikipedia.org/wiki/WebSocket
            'signalr': 'https://signalr.exchange.com' // https://en.wikipedia.org/wiki/SignalR
            'socketio': 'wss://socket.exchange.io'    // https://socket.io
        },
    },
    'version': '1.21',
    'streaming': {
        'keepAlive': 30000, // integer keep-alive rate in milliseconds
        'maxPingPongMisses': 2.0, // how many ping pong misses to drop and reconnect
        ... // other streaming options
    },
    // incremental data structures
    'orderbooks':   {}, // incremental order books indexed by symbol
    'ohlcvs':       {}, // standard CCXT OHLCVs indexed by symbol by timeframe
    'balance':      {}, // a standard CCXT balance structure, accounts indexed by currency code
    'orders':       {}, // standard CCXT order structures indexed by order id
    'trades':       {}, // arrays of CCXT trades indexed by symbol
    'tickers':      {}, // standard CCXT tickers indexed by symbol
    'transactions': {}, // standard CCXT deposits and withdrawals indexed by id or txid
    ...
}

API Unificada

A API Unificada do CCXT Pro incentiva o controle direto de fluxo para um estilo de código melhor, mais legível e arquiteturalmente superior em comparação ao uso de EventEmitters e callbacks. Esta última é considerada uma abordagem desatualizada atualmente, pois requer inversão de controle (as pessoas não estão acostumadas com o pensamento invertido).

O CCXT Pro segue a abordagem moderna e foi projetado para a sintaxe assíncrona. Por baixo dos panos, o CCXT Pro ainda precisará usar fluxo de controle invertido às vezes, por causa das dependências e das bibliotecas WebSocket que não conseguem fazer de outra forma.

O mesmo vale não apenas para JS/ES6, mas também para código assíncrono Python 3. Em PHP, os primitivos assíncronos são emprestados do ReactPHP.

A sintaxe assíncrona moderna permite combinar e dividir a execução em caminhos paralelos e depois mesclá-los, agrupá-los, priorizá-los e muito mais. Com promises, é possível converter facilmente de fluxo de controle direto em estilo assíncrono para fluxo de controle invertido em estilo callback, e vice-versa.

Tempo Real vs Throttling

O CCXT Pro suporta dois modos de loops de função tick – o modo em tempo real e o modo de throttling. Ambos são mostrados abaixo em pseudocódigo:

// real-time mode
const limit = 5 // optional
while (true) {
    try {
        const orderbook = await exchange.watchOrderBook (symbol, limit)
        // your reaction to the update takes place here
        // you arrive here after receiving the update from the exchange in real time
        console.log (orderbook) // every update
    } catch (e) {
        console.log (e)
        // throw e // uncomment to stop the loop on exceptions
    }
}
// throttling mode
const limit = 5 // optional
// await is optional, alternatively you can launch it in bg without await
await exchange.watchOrderBook (symbol, limit)
while (true) {
    // your reaction takes place here
    // you arrive here every 100 ms regardless of whether there was an update or not
    // in throttling mode offloading the orderbook with .limit () is required
    console.log (exchange.orderbooks[symbol].limit (limit))
    await exchange.sleep (100) // every 100 ms
}

No modo em tempo real, o CCXT Pro retornará o resultado assim que cada novo delta chegar da exchange. A lógica geral de uma chamada unificada em um loop em tempo real é aguardar o próximo delta e imediatamente retornar a estrutura de resultado unificada ao usuário, repetidamente. Isso é útil quando o tempo de reação é crítico ou precisa ser o mais rápido possível.

No entanto, o modo em tempo real requer experiência em programação com fluxos assíncronos quando se trata de sincronizar múltiplos loops tick paralelos. Além disso, as exchanges podem transmitir um número muito grande de atualizações durante períodos de alta atividade ou alta volatilidade. Portanto, o usuário que desenvolve um algoritmo em tempo real deve garantir que o código do lado do usuário seja capaz de consumir dados nessa velocidade. Trabalhar no modo em tempo real pode ser mais exigente em termos de recursos às vezes.

No modo de throttling, o CCXT Pro receberá e gerenciará os dados em segundo plano. O usuário é responsável por consultar os resultados de tempos em tempos, quando necessário. A lógica geral do loop de throttling é dormir na maior parte do tempo e acordar para verificar os resultados ocasionalmente. Isso geralmente é feito em alguma frequência fixa, ou "taxa de quadros". O código dentro de um loop de throttling é frequentemente mais fácil de sincronizar entre múltiplas exchanges. O racionamento do tempo gasto em um loop com throttling também ajuda a reduzir o uso de recursos ao mínimo. Isso é conveniente quando seu algoritmo é pesado e você deseja controlar a execução com precisão para evitar executá-lo com muita frequência.

A desvantagem óbvia do modo de throttling é ser menos reativo ou responsivo a atualizações. Quando um algoritmo de trading precisa aguardar alguns milissegundos antes de ser executado – uma ou duas atualizações podem chegar antes que esse tempo expire. No modo de throttling, o usuário só verificará essas atualizações na próxima vez que o loop acordar (iteração do loop), portanto, o atraso de reação pode variar dentro de alguns milissegundos ao longo do tempo.

Métodos Públicos

watchOrderBook

A interface do watchOrderBook é idêntica à do fetchOrderBook. Aceita três argumentos:

  • symbol – string, um símbolo CCXT unificado, obrigatório
  • limit – inteiro, o número máximo de bids/asks retornados, opcional
  • params – dicionário associativo, substituições opcionais conforme descrito em Substituindo Parâmetros da API Unificada

Em geral, as exchanges podem ser divididas em duas categorias:

  1. as exchanges que suportam orderbooks limitados (transmitindo apenas a parte superior da pilha de ordens)
  2. as exchanges que transmitem apenas orderbooks completos

Se a exchange aceita um argumento de limitação, o argumento limit é enviado para a exchange ao assinar o stream do orderbook por uma conexão WebSocket. A exchange então enviará apenas a quantidade especificada de ordens, o que ajuda a reduzir o tráfego. Algumas exchanges podem aceitar apenas determinados valores de limit, como 10, 25, 50, 100 e assim por diante.

Se a exchange subjacente não aceitar um argumento de limitação, a limitação é feita no lado do cliente.

O argumento limit não garante que o número de bids ou asks sempre será igual a limit. Ele designa o limite superior ou o máximo, portanto, em algum momento pode haver menos do que limit bids ou asks, mas nunca mais do que limit bids ou asks. Esse é o caso quando a exchange não tem ordens suficientes no orderbook, ou quando uma das ordens do topo do orderbook é correspondida e removida do orderbook, deixando menos de limit entradas no lado dos bids ou no lado dos asks. O espaço livre no orderbook geralmente é rapidamente preenchido com novos dados.

if (exchange.has['watchOrderBook']) {
    while (true) {
        try {
            const orderbook = await exchange.watchOrderBook (symbol, limit, params)
            console.log (new Date (), symbol, orderbook['asks'][0], orderbook['bids'][0])
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchOrderBookForSymbols

Similar ao watchOrderBook, mas aceita um array de símbolos para que você possa assinar múltiplos orderbooks em uma única mensagem.

if (exchange.has['watchOrderBookForSymbols']) {
    while (true) {
        try {
            const orderbook = await exchange.watchOrderBookForSymbols (['BTC/USDT', 'LTC/USDT'], limit, params)
            console.log (new Date (), symbol, orderbook['asks'][0], orderbook['bids'][0])
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchTicker

Algumas exchanges permitem diferentes tópicos para ouvir tickers (ex.: bookTicker). Você pode definir isso em exchange.options['watchTicker']['name']

// JavaScript
if (exchange.has['watchTicker']) {
    while (true) {
        try {
            const ticker = await exchange.watchTicker (symbol, params)
            console.log (new Date (), ticker)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}
# Python
if exchange.has['watchTicker']:
    while True:
        try:
            ticker = await exchange.watch_ticker(symbol, params)
            print(exchange.iso8601(exchange.milliseconds()), ticker)
        except Exception as e:
            print(e)
            # stop the loop on exception or leave it commented to retry
            # raise e
if ($exchange->has['watchTicker']) {
    $exchange::execute_and_run(function() use ($exchange, $symbol, $params) {
        while (true) {
            try {
                $ticker = yield $exchange->watch_ticker($symbol, $params);
                echo date('c'), ' ', json_encode($ticker), "\n";
            } catch (Exception $e) {
                echo get_class($e), ' ', $e->getMessage(), "\n";
            }
        }
    });
}

watchTickers

if (exchange.has['watchTickers']) {
    while (true) {
        try {
            const tickers = await exchange.watchTickers (symbols, params)
            console.log (new Date (), tickers)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchOHLCV

Um equívoco muito comum sobre WebSockets é que streams WS de OHLCV podem de alguma forma acelerar uma estratégia de trading. Se o objetivo do seu aplicativo é implementar trading baseado em OHLCV ou uma estratégia algorítmica especulativa, considere o seguinte cuidadosamente.

Em geral, há dois tipos de dados de trading usados nos algoritmos:

  • dados em tempo real de 1ª ordem, como orderbooks e negociações
  • dados não em tempo real de 2ª ordem, como tickers, ohlcvs, etc

Quando os desenvolvedores dizem "tempo real", geralmente significa pseudo tempo real, ou, simplificando, "tão rápido e tão próximo do tempo real quanto possível".

Os dados de 2ª ordem são sempre calculados a partir dos dados de 1ª ordem. OHLCVs são calculados a partir de negociações agregadas. Tickers são calculados a partir de negociações e orderbooks.

Algumas exchanges fazem o cálculo de OHLCVs (dados de 2ª ordem) para você no lado da exchange e enviam atualizações via WS (Binance). Outras exchanges realmente não acham isso necessário, por uma razão.

Obviamente, leva tempo para calcular candles OHLCV de 2ª ordem a partir de negociações. Além disso, enviar o candle calculado de volta a todos os usuários conectados também leva tempo. Atrasos adicionais podem ocorrer durante períodos de alta volatilidade, se uma exchange for negociada muito ativamente sob alta carga.

Não há garantia estrita de quanto tempo levará para a exchange calcular os dados de 2ª ordem e transmiti-los para você via WS. Os atrasos e defasagens nos candles OHLCV podem variar significativamente de exchange para exchange. Por exemplo, uma exchange pode enviar uma atualização de OHLCV aproximadamente 30 segundos após o fechamento real de um período correspondente. Outras exchanges podem enviar as atualizações de OHLCV atuais em intervalos regulares (digamos, uma vez a cada 100ms), enquanto na realidade as negociações podem ocorrer com muito mais frequência.

A maioria das pessoas usa WS para evitar qualquer tipo de atraso e ter dados em tempo real. Portanto, na maioria dos casos é muito melhor não esperar pela exchange. Recalcular os dados de 2ª ordem a partir dos dados de 1ª ordem por conta própria pode ser muito mais rápido e isso pode reduzir os atrasos desnecessários. Portanto, não faz muito sentido usar WS apenas para assistir candles OHLCV da exchange. Os desenvolvedores preferem usar watch_trades() e recalcular os candles OHLCV usando os métodos integrados do CCXT, como build_ohlcvc().

# Python
exchange = ccxtpro.binance()
if not exchange.has['watchOHLCV']:
    while True:
        try:
            trades = await exchange.watch_trades(symbol)
            ohlcvc = exchange.build_ohlcvc(trades, '1m')
            print(ohlcvc)
        except Exception as e:
            print(e)
            # stop the loop on exception or leave it commented to retry
            # raise e

Isso explica por que algumas exchanges razoavelmente acham que OHLCVs não são necessários no contexto WS, pois os usuários podem calcular essas informações no lado do usuário muito mais rapidamente tendo apenas um stream WS de negociações de 1ª ordem em tempo real.

Se o seu aplicativo não for muito crítico em termos de tempo, você ainda pode assinar streams de OHLCV, para fins de gráficos. Se a exchange subjacente tiver exchange.has['watchOHLCV'], você pode usar watchOHLCV()/watch_ohlcv() conforme mostrado abaixo:

if (exchange.has['watchOHLCV']) {
    while (true) {
        try {
            const candles = await exchange.watchOHLCV (symbol, timeframe, since, limit, params)
            console.log (new Date (), candles)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchOHLCVForSymbols

Similar ao watchOHLCV, mas permite múltiplas assinaturas de símbolos e timeframes

if (exchange.has['watchOHLCVForSymbols']) {
    while (true) {
        try {
            const subscriptions = [[
                ['BTC/USDT', '1d'],
                ['LTC/USDT', '5m'],
                ['ETH/USDT', '1h']
            ]]
            const candles = await exchange.watchOHLCVForSymbols (subscriptions, since, limit, params)
            console.log (new Date (), candles)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchTrades

// JavaScript
if (exchange.has['watchTrades']) {
    while (true) {
        try {
            const trades = await exchange.watchTrades (symbol, since, limit, params)
            console.log (new Date (), trades)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchTradesForSymbols

Similar ao watchTrades, mas permite assinar múltiplos símbolos em uma única chamada.

if (exchange.has['watchTradesForSymbols']) {
    while (true) {
        try {
            const trades = await exchange.watchTradesForSymbols (['LTC/USDT', 'BTC/USDT'], since, limit, params)
            console.log (new Date (), trades)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

Métodos Privados

Na maioria dos casos, a lógica de autenticação é emprestada do CCXT, já que as exchanges usam os mesmos pares de chaves e algoritmos de assinatura para APIs REST e APIs WebSocket. Consulte Configuração de Chaves de API para mais detalhes.

watchBalance

if (exchange.has['watchBalance']) {
    while (true) {
        try {
            const balance = await exchange.watchBalance (params)
            console.log (new Date (), balance)
        } catch (e) {
            console.log (e)
            // stop the loop on exception or leave it commented to retry
            // throw e
        }
    }
}

watchOrders

watchOrders (symbol = undefined, since = undefined, limit = undefined, params = {})

watchMyTrades

watchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {})

watchPositions

observa todas as posições abertas e retorna uma lista de estrutura de posição

watchPositions (symbols = undefined, since = undefined, limit = undefined, params = {}) 

createOrderWs

createOrderWs (symbol: string, type: OrderType, side: OrderSide, amount: number, price: number = undefined, params = {})

editOrderWs

// JavaScript
editOrderWs (id, symbol: string, type: OrderType, side: OrderSide, amount: number, price: number = undefined, params = {})

cancelOrderWs

cancelOrderWs(id: string, symbol: string = undefined, params = {})

cancelOrdersWs

cancelOrdersWs(ids: string[], symbol: string = undefined, params = {})

cancelAllOrdersWs

cancelAllOrdersWs(symbol: string = undefined, params = {})

watchTransactions

- this method is a work in progress now (may be unavailable)

Manipulador personalizado

Se você quiser ter acesso às mensagens recebidas brutas e usar seus próprios manipuladores personalizados, pode sobrescrever o método handleMessage/handle_message da exchange, da seguinte forma:

A) Por herança:

class myExchange extends ccxt.pro.coinbase {
    handleMessage (wsClient, data) {
        console.log("Raw incoming message:", message) // this is the raw update
        super.handleMessage(wsClient, data);
        // your extra logic here
    }
}
const ex = new myExchange();
ex.watchTicker('BTC/USDT');

B) sobrescrevendo o método:

function myHandler(ws, data, orignal_handler){
    orignal_handler(ws, data); // trigger original `handleMessage`
    if (your_condition) {
        // execute your additional code
    }
}

const ex = new ccxt.pro.binance();
const original_handler = ex.handleMessage.bind(ex);
ex.handleMessage = (ws, data) => myHandler(ws, data, original_handler);
ex.watchTicker('BTC/USDT');

Tratamento de Erros

Em caso de erro, o CCXT Pro lançará uma exceção padrão do CCXT. Consulte Tratamento de Erros para mais detalhes.

Nesta página