CCXT

Manual de CCXT Pro

CCXT Pro es una parte gratuita de CCXT que añade soporte para streaming WebSocket: https://github.com/ccxt/ccxt/issues/15171

Manual

CCXT Pro es una parte gratuita de CCXT que añade soporte para streaming WebSocket: https://github.com/ccxt/ccxt/issues/15171

La pila de CCXT Pro está construida sobre CCXT y extiende las clases principales de CCXT, utilizando:

  • Mixins a nivel de prototipo en JavaScript
  • Herencia múltiple en Python
  • Traits en PHP
  • Herencia de clases en Java (las clases de exchange pro extienden las clases base de exchange)

CCXT Pro depende en gran medida del transpilador de CCXT para el soporte multilenguaje.

                                 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

La biblioteca CCXT Pro actualmente soporta los siguientes 74 mercados de criptomonedas y APIs de trading 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 es la lista de exchanges en CCXT Pro con soporte para APIs WebSockets. Esta lista se actualizará con nuevos exchanges de forma periódica.

Lista completa de exchanges disponibles en CCXT vía REST: Mercados de intercambio de criptomonedas compatibles.

Uso

- 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

Requisitos previos

La mejor manera de entender CCXT Pro es asegurarse de comprender todo el Manual de CCXT y practicar primero con CCXT estándar. CCXT Pro toma prestado de CCXT. Ambas bibliotecas comparten muchos puntos en común, entre ellos:

  • los conceptos de API pública y API privada autenticada
  • mercados, símbolos, códigos e identificadores de divisas
  • estructuras y formatos de datos unificados, libros de órdenes, operaciones, órdenes, velas, marcos temporales, ...
  • excepciones y mapeos de errores
  • autenticación y claves de API (para feeds y llamadas privadas)
  • opciones de configuración

El público objetivo de CCXT Pro está compuesto principalmente por traders algorítmicos profesionales y desarrolladores. Para trabajar de manera eficiente con esta biblioteca, el usuario debe estar bien familiarizado con los conceptos de streaming. Es necesario comprender las diferencias subyacentes entre las APIs de streaming basadas en conexión (WebSocket, CCXT Pro) y las APIs basadas en solicitud-respuesta (REST, CCXT).

El flujo general de estilo asíncrono para una aplicación CCXT es el siguiente:


// 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
    }
}

En CCXT Pro, cada método RESTful unificado público y privado que tiene un prefijo fetch* también tiene un método homólogo basado en streams con el prefijo watch*, como se muestra a continuación:

  • 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 (detiene la suscripción en segundo plano para los métodos con watch)
    • unWatchOrderBook
    • unWatchOrderBooksForSymbols
    • unWatchTrades
    • unWatchTradesForSymbols
    • unWatchOHLCVForSymbols
    • unWatchOrderBookForSymbols
    • unWatchPositions
    • unWatchTickers
    • unWatchMyTrades
    • unWatchTicker
    • unWatchOHLCV
    • unWatchOrders

La API de Streaming Unificada de CCXT Pro hereda los patrones de uso de CCXT para facilitar la migración.

El flujo general de estilo asíncrono para una aplicación CCXT Pro (en contraposición a una aplicación CCXT descrita anteriormente) se muestra a continuación:


// 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
    }
}

Ese patrón de uso generalmente se encapsula en un método de lógica de negocio central llamado "función tick()", ya que reitera una reacción a los eventos entrantes (también conocidos como ticks). De los dos ejemplos anteriores es evidente que el patrón de uso genérico en CCXT Pro y CCXT es idéntico.

Muchas de las reglas y conceptos de CCXT también se aplican a CCXT Pro:

  • CCXT Pro cargará los mercados y los almacenará en caché en la primera llamada a un método de API unificado
  • CCXT Pro llamará a los métodos RESTful de CCXT de forma interna cuando sea necesario
  • CCXT Pro lanzará las excepciones estándar de CCXT cuando sea necesario
  • ...

Especificidades del Streaming

A pesar de las numerosas similitudes, las APIs basadas en streaming tienen sus propias particularidades debido a su naturaleza orientada a conexiones.

Contar con una interfaz basada en conexión implica mecanismos de gestión de conexiones. CCXT Pro gestiona las conexiones de forma transparente para el usuario. Cada instancia de exchange gestiona su propio conjunto de conexiones.

En la primera llamada a cualquier método watch*(), la biblioteca establecerá una conexión a un stream/recurso específico del exchange y la mantendrá. Si la conexión ya existe, se reutiliza. La biblioteca gestionará las secuencias de mensajes de solicitud/respuesta de suscripción, así como la autenticación/firma si el stream solicitado es privado.

La biblioteca también monitorizará el estado del enlace y mantendrá la conexión activa. Ante una excepción crítica, una desconexión o un tiempo de espera/fallo de conexión, la siguiente iteración de la función tick llamará al método watch, que activará una reconexión. De este modo, la biblioteca gestiona las desconexiones y reconexiones para el usuario de forma transparente. CCXT Pro aplica la limitación de velocidad necesaria y los retrasos de reconexión con retroceso exponencial. Toda esa funcionalidad está habilitada por defecto y puede configurarse a través de las propiedades del exchange, como de costumbre.

La mayoría de los exchanges solo tienen una URL base única para las APIs de streaming (habitualmente WebSocket, que comienza con ws:// o wss://). Algunos pueden tener más de una URL por cada stream, dependiendo del feed en cuestión.

Las APIs de Streaming de los exchanges pueden clasificarse en dos categorías diferentes:

  • sub o subscribe permite solo recibir datos
  • pub o publish permite enviar y recibir datos

Sub

Una interfaz sub generalmente permite suscribirse a un flujo de datos y escucharlo. La mayoría de los exchanges que soportan WebSockets solo ofrecerán una API de tipo sub. El tipo sub incluye el streaming de datos públicos de mercado. A veces los exchanges también permiten suscribirse a datos privados del usuario. Una vez que el usuario se suscribe a un feed de datos, el canal comienza a funcionar de forma unidireccional, enviando actualizaciones del exchange al usuario de manera continua.

Tipos de streams de datos públicos más habituales:

  • libro de órdenes (el más común) - actualizaciones sobre órdenes añadidas, editadas y eliminadas (también conocidas como deltas de cambio)
  • actualizaciones del ticker al cambiar las estadísticas de 24 horas
  • feed de ejecuciones (también común) - un stream en tiempo real de operaciones públicas
  • feed de velas ohlcv
  • heartbeat
  • chat/trollbox del exchange

Tipos menos comunes de streams de datos privados del usuario:

  • el stream de operaciones privadas del usuario
  • actualizaciones de órdenes en tiempo real
  • actualizaciones de saldo
  • streams personalizados
  • streams específicos del exchange y otros

Pub

Una interfaz pub generalmente permite a los usuarios enviar solicitudes de datos al servidor. Esto normalmente incluye acciones comunes del usuario, como:

  • colocar órdenes
  • cancelar órdenes
  • realizar solicitudes de retiro
  • publicar mensajes en el chat/trollbox
  • etc

Algunos exchanges no ofrecen una API WS de tipo pub, solo ofrecerán una API WS de tipo sub. Sin embargo, existen exchanges que también disponen de una API de Streaming completa. En la mayoría de los casos, un usuario no puede operar de forma efectiva disponiendo únicamente de la API de Streaming. Los exchanges transmitirán datos públicos de mercado mediante sub, y la API REST sigue siendo necesaria para la parte pub cuando esta falta.

unWatch

Cada método watchX establece una suscripción con un stream y recibirá actualizaciones continuas del exchange. Aunque dejes de obtener el valor de retorno del método watchX, el stream seguirá enviando datos, los cuales son gestionados y almacenados en segundo plano. Para detener esas suscripciones en segundo plano, debes usar el método unWatch (p. ej. watchTrades -> unWatchTrades).

Estructuras de Datos Incrementales

En muchos casos, debido a la naturaleza unidireccional de los feeds de datos subyacentes, la aplicación que escucha en el lado del cliente debe mantener una instantánea local de los datos en memoria y combinar las actualizaciones recibidas del servidor del exchange con la instantánea local. Las actualizaciones que provienen del exchange también se denominan frecuentemente deltas, porque en la mayoría de los casos solo contendrán los cambios entre dos estados de los datos y no incluirán los datos que no han cambiado, lo que hace necesario almacenar el estado actual S en caché localmente de todos los objetos de datos relevantes.

Toda esa funcionalidad es gestionada por CCXT Pro para el usuario. Para trabajar con CCXT Pro, el usuario no tiene que rastrear ni gestionar suscripciones ni los datos relacionados. CCXT Pro mantendrá una caché de estructuras en memoria para gestionar la complejidad subyacente.

Cada actualización entrante indica qué partes de los datos han cambiado y el lado receptor "incrementa" el estado local S combinando la actualización sobre el estado actual S y pasando al siguiente estado local S'. En términos de CCXT Pro, esto se denomina "estado incremental" y las estructuras involucradas en el proceso de almacenamiento y actualización del estado en caché se denominan "estructuras incrementales". CCXT Pro introduce varias nuevas clases base para gestionar el estado incremental cuando es necesario.

Las estructuras incrementales devueltas por los métodos unificados de CCXT Pro son generalmente de uno de dos tipos:

  1. Objeto decodificado en JSON (object en JavaScript, dict en Python, array() en PHP). Este tipo puede devolverse desde métodos públicos y privados como watchOrderBook, watchTicker, watchBalance, watchOrder, etc.
  2. Un array/lista de objetos (generalmente ordenados cronológicamente). Este tipo puede devolverse desde métodos como watchOHLCV, watchTrades, watchMyTrades, watchOrders, etc.

Los métodos unificados que devuelven arrays como watchOHLCV, watchTrades, watchMyTrades, watchOrders, se basan en la capa de caché. El usuario debe comprender el funcionamiento interno de la capa de caché para trabajar con ella de manera eficiente.

La caché es una cola de doble extremo de tamaño fijo, también conocida como array/lista. La biblioteca CCXT Pro tiene un límite razonable en el número de objetos almacenados en memoria. Por defecto, las estructuras de array en caché almacenarán hasta 1000 entradas de cada tipo (las 1000 operaciones más recientes, las 1000 velas más recientes, las 1000 órdenes más recientes). El número máximo permitido puede ser configurado por el usuario en el momento de la instanciación o posteriormente:

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

# or

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

Los límites de caché deben establecerse antes de llamar a cualquier método watch y no pueden cambiar durante la ejecución del programa.

Cuando hay espacio disponible en la caché, los nuevos elementos se añaden simplemente al final. Si no hay suficiente espacio para un nuevo elemento, el elemento más antiguo se elimina del principio de la caché para liberar espacio. Así, por ejemplo, la caché crece de 0 a 1000 operaciones más recientes y luego se mantiene en un máximo de 1000 operaciones más recientes, renovando constantemente los datos almacenados con cada nueva actualización que llega del exchange. Se asemeja a una ventana deslizante o una puerta corredera, que se muestra a continuación:

      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

El usuario puede configurar los límites de caché usando exchange.options como se mostró anteriormente. No confundas los límites de caché con el límite de paginación.

Ten en cuenta que los parámetros since y limit de paginación basada en fechas tienen un significado diferente y siempre se aplican dentro de la ventana en caché. Si el usuario especifica un argumento since en la llamada a watchTrades(), CCXT Pro devolverá todas las operaciones en caché con timestamp >= since. Si el usuario no especifica un argumento since, CCXT Pro devolverá las operaciones en caché desde el principio de la ventana deslizante. Si el usuario especifica un argumento limit, la biblioteca devolverá hasta limit velas comenzando desde since o desde el inicio de la caché. Por ese motivo, el usuario no puede paginar más allá del marco en caché debido a las especificidades en tiempo real de WebSocket.

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

Si desea obtener siempre solo la operación más reciente, debe instanciar el exchange con la bandera newUpdates establecida en true.

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

El modo newUpdates sigue utilizando la caché deslizante en segundo plano, pero el usuario solo recibirá las nuevas actualizaciones. Esto se debe a que algunos exchanges utilizan estructuras incrementales, por lo que necesitamos mantener una caché de objetos ya que el exchange puede proporcionar únicamente información parcial, como actualizaciones de estado.

El resultado del modo newUpdates será una o más actualizaciones que hayan ocurrido desde la última vez que exchange.watchMethod se resolvió. CCXT Pro puede devolver una o más órdenes que se actualizaron desde la llamada anterior. El resultado de llamar a exchange.watchOrders tendrá el aspecto que se muestra a continuación:

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

Aviso de obsolescencia: en el futuro newUpdates: true será el modo predeterminado y tendrá que establecer newUpdates en false para obtener la caché deslizante.

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

El módulo CCXT Pro importado envuelve a CCXT dentro de sí mismo: cada exchange instanciado a través de CCXT Pro tiene todos los métodos de CCXT además de la funcionalidad adicional.

Instanciación

CCXT Pro está diseñado para la sintaxis async/await y depende en gran medida de primitivas asíncronas como las promesas y los futuros.

Crear una instancia de exchange de CCXT Pro es prácticamente idéntico a crear una instancia de exchange de CCXT.

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

Python

La implementación en Python de CCXT Pro se basa en el módulo integrado asyncio y en particular en el Event Loop. En Python es posible suministrar una instancia del bucle de eventos de asyncio en los argumentos del constructor como se muestra a continuación (idéntico a 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

En PHP las primitivas asíncronas se toman prestadas de ReactPHP. La implementación en PHP de CCXT Pro se basa en Promise y en EventLoop en particular. En PHP el usuario debe suministrar una instancia del bucle de eventos de ReactPHP en los argumentos del constructor como se muestra a continuación:

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));
        }
    }

Propiedades del Exchange

Cada instancia de CCXT Pro contiene todas las propiedades de la instancia CCXT subyacente. Además de las propiedades estándar de CCXT, la instancia de CCXT Pro incluye las siguientes:

{
    '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

La API Unificada de CCXT Pro fomenta el flujo de control directo para lograr un mejor estilo de código, más legible y arquitectónicamente superior en comparación con el uso de EventEmitters y callbacks. Este último enfoque se considera obsoleto hoy en día, ya que requiere inversión del control (la gente no está acostumbrada al pensamiento invertido).

CCXT Pro adopta el enfoque moderno y está diseñado para la sintaxis asíncrona. Internamente, CCXT Pro aún tendrá que usar flujo de control invertido en ocasiones debido a las dependencias y las librerías WebSocket que no pueden hacer otra cosa.

Lo mismo aplica no solo para JS/ES6 sino también para el código asíncrono de Python 3. En PHP las primitivas asíncronas se toman prestadas de ReactPHP.

La sintaxis asíncrona moderna permite combinar y dividir la ejecución en caminos paralelos para luego fusionarlos, agruparlos, priorizarlos y mucho más. Con las promesas se puede convertir fácilmente de un flujo de control de estilo asíncrono directo a un flujo de control de estilo callback invertido, y viceversa.

Tiempo Real vs Limitación de Frecuencia

CCXT Pro admite dos modos de bucles de funciones de tick: el modo en tiempo real y el modo de limitación de frecuencia. Ambos se muestran a continuación en 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
}

En el modo en tiempo real, CCXT Pro devolverá el resultado tan pronto como llegue cada nuevo delta desde el exchange. La lógica general de una llamada unificada en un bucle en tiempo real consiste en esperar el siguiente delta y devolver inmediatamente la estructura de resultado unificada al usuario, una y otra vez. Esto es útil cuando el tiempo de reacción es crítico o debe ser lo más rápido posible.

Sin embargo, el modo en tiempo real requiere experiencia en programación con flujos asíncronos a la hora de sincronizar múltiples bucles de tick en paralelo. Además, los exchanges pueden transmitir un número muy elevado de actualizaciones durante períodos de alta actividad o alta volatilidad. Por ello, el usuario que desarrolla un algoritmo en tiempo real debe asegurarse de que el código en espacio de usuario sea capaz de consumir datos a esa velocidad. Trabajar en modo en tiempo real puede ser a veces más exigente en cuanto a recursos.

En el modo de limitación de frecuencia, CCXT Pro recibirá y gestionará los datos en segundo plano. El usuario es responsable de consultar los resultados de vez en cuando cuando sea necesario. La lógica general del bucle de limitación consiste en dormir la mayor parte del tiempo y despertar ocasionalmente para comprobar los resultados. Esto se hace normalmente a una frecuencia fija o, en otras palabras, a una "tasa de fotogramas". El código dentro de un bucle de limitación suele ser más fácil de sincronizar entre múltiples exchanges. El racionamiento del tiempo invertido en un bucle con limitación también ayuda a reducir el uso de recursos al mínimo. Esto es práctico cuando su algoritmo es pesado y desea controlar la ejecución con precisión para evitar ejecutarlo con demasiada frecuencia.

La desventaja obvia del modo de limitación de frecuencia es ser menos reactivo o sensible a las actualizaciones. Cuando un algoritmo de trading tiene que esperar cierta cantidad de milisegundos antes de ejecutarse, puede llegar una o dos actualizaciones antes de que ese tiempo expire. En el modo de limitación, el usuario solo comprobará esas actualizaciones en el siguiente despertar (iteración del bucle), por lo que el retardo de reacción puede variar dentro de cierta cantidad de milisegundos a lo largo del tiempo.

Métodos Públicos

watchOrderBook

La interfaz de watchOrderBook es idéntica a la de fetchOrderBook. Acepta tres argumentos:

  • symbol – cadena de texto, un símbolo CCXT unificado, obligatorio
  • limit – entero, el número máximo de ofertas de compra/venta devueltas, opcional
  • params – diccionario asociativo, sobreescrituras opcionales como se describe en Sobreescritura de Parámetros de la API Unificada

En general, los exchanges se pueden dividir en dos categorías:

  1. los exchanges que admiten libros de órdenes limitados (transmitiendo solo la parte superior de la pila de órdenes)
  2. los exchanges que transmiten solo libros de órdenes completos

Si el exchange acepta un argumento de limitación, el argumento limit se envía al exchange al suscribirse al flujo del libro de órdenes a través de una conexión WebSocket. El exchange enviará entonces solo la cantidad de órdenes especificada, lo que ayuda a reducir el tráfico. Algunos exchanges solo pueden aceptar ciertos valores de limit, como 10, 25, 50, 100, etc.

Si el exchange subyacente no acepta un argumento de limitación, la limitación se realiza en el lado del cliente.

El argumento limit no garantiza que el número de ofertas de compra o de venta sea siempre igual a limit. Designa el límite superior o el máximo, por lo que en algún momento puede haber menos de limit ofertas de compra o de venta, pero nunca más de limit. Este es el caso cuando el exchange no tiene suficientes órdenes en el libro de órdenes, o cuando una de las órdenes superiores del libro de órdenes se empareja y se elimina del libro de órdenes, dejando menos de limit entradas en el lado de las ofertas de compra o en el lado de las ofertas de venta. El espacio libre en el libro de órdenes generalmente se llena rápidamente con nuevos datos.

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 a watchOrderBook pero acepta un array de símbolos para que pueda suscribirse a múltiples libros de órdenes en un solo mensaje.

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

Algunos exchanges permiten diferentes temas para escuchar tickers (por ejemplo: bookTicker). Puede configurar esto en 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

Un error muy común sobre los WebSockets es creer que los flujos OHLCV de WS pueden de algún modo acelerar una estrategia de trading. Si el propósito de su aplicación es implementar trading basado en OHLCV o una estrategia algorítmica especulativa, considere lo siguiente cuidadosamente.

En general, existen dos tipos de datos de trading utilizados en los algoritmos:

  • datos en tiempo real de primer orden como libros de órdenes y operaciones
  • datos de segundo orden no en tiempo real como tickers, ohlcvs, etc.

Cuando los desarrolladores dicen "tiempo real", generalmente se refieren a pseudo tiempo real, o, dicho simplemente, "tan rápido y tan cerca del tiempo real como sea posible".

Los datos de segundo orden se calculan siempre a partir de los datos de primer orden. Los OHLCVs se calculan a partir de operaciones agregadas. Los tickers se calculan a partir de operaciones y libros de órdenes.

Algunos exchanges realizan el cálculo de OHLCVs (datos de segundo orden) por usted en el lado del exchange y le envían actualizaciones a través de WS (Binance). Otros exchanges no consideran que esto sea necesario, con razón.

Obviamente, lleva tiempo calcular las velas OHLCV de segundo orden a partir de las operaciones. Además, enviar la vela calculada de vuelta a todos los usuarios conectados también lleva tiempo. Pueden producirse retrasos adicionales durante períodos de alta volatilidad si un exchange opera muy activamente bajo alta carga.

No existe una garantía estricta sobre cuánto tiempo tardará el exchange en calcular los datos de segundo orden y transmitirlos a usted a través de WS. Los retrasos y desfases en las velas OHLCV pueden variar significativamente de un exchange a otro. Por ejemplo, un exchange puede enviar una actualización OHLCV aproximadamente 30 segundos después del cierre real del período correspondiente. Otros exchanges pueden enviar las actualizaciones OHLCV actuales a intervalos regulares (digamos, una vez cada 100ms), mientras que en realidad las operaciones pueden ocurrir con mucha más frecuencia.

La mayoría de las personas usan WS para evitar cualquier tipo de retrasos y tener datos en tiempo real. Por lo tanto, en la mayoría de los casos es mucho mejor no esperar al exchange. Recalcular los datos de segundo orden a partir de los datos de primer orden por cuenta propia puede ser mucho más rápido y puede reducir los retrasos innecesarios. Por ello, no tiene mucho sentido usar WS únicamente para observar las velas OHLCV del exchange. Los desarrolladores preferirían usar watch_trades() y recalcular las velas OHLCV usando los métodos integrados de 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

Eso explica por qué algunos exchanges razonablemente consideran que los OHLCVs no son necesarios en el contexto de WS, ya que los usuarios pueden calcular esa información en el espacio de usuario mucho más rápido teniendo solo un flujo WS de operaciones en tiempo real de primer orden.

Si su aplicación no es muy crítica en tiempo, puede seguir suscribiéndose a flujos OHLCV, con fines de representación gráfica. Si el exchange subyacente tiene exchange.has['watchOHLCV'], puede usar watchOHLCV()/watch_ohlcv() como se muestra a continuación:

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 a watchOHLCV pero permite múltiples suscripciones de símbolos y marcos temporales

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 a watchTrades pero permite suscribirse a múltiples símbolos en una sola llamada.

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

En la mayoría de los casos la lógica de autenticación se toma prestada de CCXT, ya que los exchanges utilizan los mismos pares de claves y algoritmos de firma para las APIs REST y las APIs WebSocket. Consulte Configuración de Claves API para más detalles.

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 las posiciones abiertas y devuelve una lista de estructura de posición

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)

Manejador personalizado

Si deseas tener acceso a los mensajes entrantes sin procesar y usar tus propios manejadores personalizados, puedes sobreescribir el método handleMessage/handle_message del exchange, de la siguiente manera:

A) Por herencia:

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) sobreescribiendo el 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');

Manejo de errores

En caso de error, CCXT Pro lanzará una excepción estándar de CCXT; consulta Manejo de errores para más detalles.

En esta página