CCXT Pro Handbuch
CCXT Pro ist ein kostenloser Teil von CCXT, der Unterstützung für WebSocket-Streaming hinzufügt: https://github.com/ccxt/ccxt/issues/15171
Handbuch
CCXT Pro ist ein kostenloser Teil von CCXT, der Unterstützung für WebSocket-Streaming hinzufügt: https://github.com/ccxt/ccxt/issues/15171
Der CCXT Pro-Stack basiert auf CCXT und erweitert die CCXT-Kernklassen mithilfe von:
- JavaScript Prototype-Level-Mixins
- Python-Mehrfachvererbung
- PHP Traits
- Java-Klassenvererbung (Pro-Exchange-Klassen erweitern Basis-Exchange-Klassen)
CCXT Pro stützt sich stark auf den Transpiler von CCXT für die Mehrsprachenunterstützung.
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 |
| |
+=============================================================+Börsen
Die CCXT Pro-Bibliothek unterstützt derzeit die folgenden 74 Kryptowährungs-Börsenmärkte und WebSocket-Handels-APIs:| logo | id | name | ver | type | certified | pro |
|---|---|---|---|---|---|---|
| aftermath | AftermathFinance | |||||
| alpaca | Alpaca | |||||
| apex | Apex | |||||
| arkham | ARKHAM | |||||
| ascendex | AscendEX | |||||
| aster | Aster | |||||
| backpack | Backpack | |||||
| bequant | Bequant | |||||
| binance | Binance | |||||
| binancecoinm | Binance COIN-M | |||||
| binanceus | Binance US | |||||
| binanceusdm | Binance USDⓈ-M | |||||
![]() | bingx | BingX | ||||
| bitfinex | Bitfinex | |||||
| bitget | Bitget | |||||
| bithumb | Bithumb | |||||
| bitmart | BitMart | |||||
| bitmex | BitMEX | |||||
| bitopro | BitoPro | |||||
| bitrue | Bitrue | |||||
| bitstamp | Bitstamp | |||||
![]() | bittrade | BitTrade | ||||
| bitvavo | Bitvavo | |||||
| blockchaincom | Blockchain.com | |||||
| blofin | BloFin | |||||
| bullish | Bullish | |||||
| bybit | Bybit | |||||
| bybiteu | Bybit EU | |||||
| bydfi | BYDFi | |||||
![]() | cex | CEX.IO | ||||
![]() | coinbase | Coinbase Advanced | ||||
| coinbaseexchange | Coinbase Exchange | |||||
| coinbaseinternational | Coinbase International | |||||
![]() | coinex | CoinEx | ||||
![]() | cryptocom | Crypto.com | ||||
| deepcoin | DeepCoin | |||||
![]() | deribit | Deribit | ||||
| derive | derive | |||||
| dydx | dYdX | |||||
| gate | Gate | |||||
![]() | gemini | Gemini | ||||
| grvt | GRVT | |||||
| hashkey | HashKey Global | |||||
![]() | hollaex | HollaEx | ||||
![]() | htx | HTX | ||||
| hyperliquid | Hyperliquid | |||||
![]() | independentreserve | Independent Reserve | ||||
![]() | kraken | Kraken | ||||
![]() | krakenfutures | Kraken Futures | ||||
![]() | kucoin | KuCoin | ||||
![]() | kucoinfutures | KuCoin Futures | ||||
![]() | lbank | LBank | ||||
| lighter | Lighter | |||||
![]() | luno | luno | ||||
![]() | mexc | MEXC Global | ||||
| modetrade | Mode Trade | |||||
![]() | myokx | MyOKX (EEA) | ||||
![]() | ndax | NDAX | ||||
![]() | okx | OKX | ||||
![]() | okxus | OKX (US) | ||||
| onetrading | One Trading | |||||
| oxfun | OXFUN | |||||
| p2b | p2b | |||||
| pacifica | Pacifica | |||||
| paradex | Paradex | |||||
![]() | phemex | Phemex | ||||
![]() | poloniex | Poloniex | ||||
| toobit | Toobit | |||||
![]() | upbit | Upbit | ||||
| weex | Weex | |||||
![]() | whitebit | WhiteBit | ||||
![]() | woo | WOO X | ||||
| woofipro | WOOFI PRO | |||||
![]() | xt | XT |
Dies ist die Liste der Börsen in CCXT Pro mit Unterstützung für WebSockets-APIs. Diese Liste wird regelmäßig mit neuen Börsen aktualisiert.
Vollständige Liste der über REST in CCXT verfügbaren Börsen: Unterstützte Kryptowährungs-Handelsmärkte.
Verwendung
- 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 appreciatedVoraussetzungen
Der beste Weg, CCXT Pro zu verstehen, besteht darin, sicherzustellen, dass Sie das gesamte CCXT-Handbuch verstehen und zunächst Standard-CCXT praktisch anwenden. CCXT Pro baut auf CCXT auf. Die beiden Bibliotheken teilen viele Gemeinsamkeiten, darunter:
- die Konzepte der öffentlichen API und der privaten authentifizierten API
- Märkte, Symbole, Währungscodes und IDs
- einheitliche Datenstrukturen und -formate, Orderbücher, Trades, Orders, Kerzen, Zeitrahmen, ...
- Ausnahmen und Fehlerzuordnungen
- Authentifizierung und API-Schlüssel (für private Feeds und Aufrufe)
- Konfigurationsoptionen
Das Zielpublikum von CCXT Pro besteht hauptsächlich aus professionellen algorithmischen Händlern und Entwicklern. Um effizient mit dieser Bibliothek arbeiten zu können, muss der Benutzer mit den Konzepten des Streamings vertraut sein. Man muss die grundlegenden Unterschiede zwischen verbindungsbasierten Streaming-APIs (WebSocket, CCXT Pro) und anfrage-/antwortbasierten APIs (REST, CCXT) verstehen.
Der allgemeine asynchrone Ablauf für eine CCXT-Anwendung ist wie folgt:
// 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
}
}In CCXT Pro hat jede öffentliche und private einheitliche RESTful-Methode mit dem Präfix fetch* auch eine entsprechende streambasierte Gegenstückmethode mit dem Präfix watch*, wie folgt:
- Öffentliche API
fetchStatus→watchStatusfetchOrderBook→watchOrderBookfetchOrderBookForSymbols→watchOrderBookForSymbolsfetchTicker→watchTickerfetchTickers→watchTickersfetchOHLCV→watchOHLCVfetchOHLCVForSymbols→watchOHLCVForSymbolsfetchTrades→watchTradesfetchTradesForSymbols→watchTradesForSymbolsfetchBidsAsks→watchBidsAsksfetchLiquidations→watchLiquidationsfetchLiquidationsForSymbols→watchLiquidationsForSymbols
- Private API
fetchBalance→watchBalancefetchOrders→watchOrdersfetchOrdersForSymbols→watchOrdersForSymbolsfetchMyTrades→watchMyTradesfetchPosition→watchPositionfetchPositions→watchPositionsfetchLiquidations→watchLiquidationsfetchMyLiquidations→watchMyLiquidationsfetchMyLiquidationsForSymbols→watchMyLiquidationsForSymbolsfetchFundingRates→watchFundingRates
- REST-Alternativen
fetchTrades→fetchTradesWscreateOrder→createOrderWseditOrder→editOrderWscancelOrder→cancelOrderWscancelOrders→cancelOrdersWscancelAllOrders→cancelAllOrdersWs- usw. ...
- unWatch (beendet Hintergrund-Abonnements für
watch-Methoden)unWatchOrderBookunWatchOrderBooksForSymbolsunWatchTradesunWatchTradesForSymbolsunWatchOHLCVForSymbolsunWatchOrderBookForSymbolsunWatchPositionsunWatchTickersunWatchMyTradesunWatchTickerunWatchOHLCVunWatchOrders
Die einheitliche CCXT Pro Streaming-API übernimmt CCXT-Verwendungsmuster, um die Migration zu erleichtern.
Der allgemeine asynchrone Ablauf für eine CCXT Pro-Anwendung (im Gegensatz zu einer CCXT-Anwendung oben) ist unten dargestellt:
// 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
}
}Dieses Verwendungsmuster wird üblicherweise in eine zentrale Geschäftslogik-Methode namens „eine tick()-Funktion" eingebettet, da sie eine Reaktion auf eingehende Ereignisse (auch Ticks genannt) wiederholt. Aus den beiden obigen Beispielen wird deutlich, dass das generische Verwendungsmuster in CCXT Pro und CCXT identisch ist.
Viele der CCXT-Regeln und -Konzepte gelten auch für CCXT Pro:
- CCXT Pro lädt Märkte und speichert diese beim ersten Aufruf einer einheitlichen API-Methode im Cache
- CCXT Pro ruft bei Bedarf intern CCXT RESTful-Methoden auf
- CCXT Pro wirft bei Bedarf Standard-CCXT-Ausnahmen
- ...
Streaming-Besonderheiten
Trotz der zahlreichen Gemeinsamkeiten haben streamingbasierte APIs aufgrund ihrer verbindungsbasierten Natur eigene Besonderheiten.
Ein verbindungsbasiertes Interface erfordert Mechanismen zur Verbindungsverwaltung. Verbindungen werden von CCXT Pro transparent für den Benutzer verwaltet. Jede Börseninstanz verwaltet ihre eigene Gruppe von Verbindungen.
Beim ersten Aufruf einer watch*()-Methode stellt die Bibliothek eine Verbindung zu einem bestimmten Stream/einer bestimmten Ressource der Börse her und hält diese aufrecht. Wenn die Verbindung bereits besteht, wird sie wiederverwendet. Die Bibliothek verarbeitet die Abonnement-Anfrage-/Antwort-Nachrichtensequenzen sowie die Authentifizierung/Signierung, sofern der angeforderte Stream privat ist.
Die Bibliothek überwacht auch den Status der Uplink-Verbindung und hält die Verbindung aufrecht. Bei einer kritischen Ausnahme, einer Trennung oder einem Verbindungstimeout/-fehler ruft die nächste Iteration der Tick-Funktion die watch-Methode auf, die eine Neuverbindung auslöst. Auf diese Weise behandelt die Bibliothek Trennungen und Neuverbindungen transparent für den Benutzer. CCXT Pro wendet die erforderliche Ratenbegrenzung und exponentiell ansteigende Wartezeiten bei der Neuverbindung an. All diese Funktionalität ist standardmäßig aktiviert und kann über Börseneigenschaften konfiguriert werden, wie gewohnt.
Die meisten Börsen haben nur eine einzige Basis-URL für Streaming-APIs (in der Regel WebSocket, beginnend mit ws:// oder wss://). Einige können mehr als eine URL pro Stream haben, je nach dem betreffenden Feed.
Streaming-APIs von Börsen lassen sich in zwei verschiedene Kategorien einteilen:
- sub oder subscribe erlaubt nur Empfang
- pub oder publish erlaubt Senden und Empfangen
Sub
Ein sub-Interface erlaubt es in der Regel, einen Datenstrom zu abonnieren und auf diesen zu hören. Die meisten Börsen, die WebSockets unterstützen, bieten nur einen sub-API-Typ an. Der sub-Typ umfasst das Streamen öffentlicher Marktdaten. Manchmal erlauben Börsen auch das Abonnieren privater Benutzerdaten. Nachdem der Benutzer einen Datenfeed abonniert hat, beginnt der Kanal effektiv einseitig zu arbeiten und sendet kontinuierlich Updates von der Börse an den Benutzer.
Häufig vorkommende Arten öffentlicher Datenströme:
- Orderbuch (am häufigsten) – Updates zu hinzugefügten, bearbeiteten und gelöschten Orders (auch Change-Deltas genannt)
- Ticker-Updates bei Änderung der 24-Stunden-Statistiken
- Fills-Feed (ebenfalls häufig) – ein Live-Stream öffentlicher Trades
- OHLCV-Kerzenfeed
- Heartbeat
- Börsen-Chat/Trollbox
Weniger häufige Arten privater Benutzerdatenströme:
- der Stream privater Trades des Benutzers
- Live-Order-Updates
- Kontostand-Updates
- benutzerdefinierte Streams
- börsenspezifische und andere Streams
Pub
Ein pub-Interface erlaubt es Benutzern in der Regel, Datenanfragen an den Server zu senden. Dies umfasst üblicherweise gängige Benutzeraktionen wie:
- Orders aufgeben
- Orders stornieren
- Auszahlungsanfragen stellen
- Chat-/Trollbox-Nachrichten posten
- usw.
Einige Börsen bieten keine pub WS-API an, sondern nur eine sub WS-API. Es gibt jedoch Börsen, die auch eine vollständige Streaming-API anbieten. In den meisten Fällen kann ein Benutzer nicht effektiv operieren, wenn nur die Streaming-API vorhanden ist. Börsen streamen öffentliche Marktdaten über sub, und die REST-API wird weiterhin für den pub-Teil benötigt, wo dieser fehlt.
unWatch
Jede watchX-Methode richtet ein Abonnement mit einem Stream ein und erhält kontinuierlich Updates von der Börse. Auch wenn Sie aufhören, den Rückgabewert der watchX-Methode abzurufen, sendet der Stream weiterhin Daten, die im Hintergrund verarbeitet und gespeichert werden. Um diese Hintergrund-Abonnements zu beenden, sollten Sie die unWatch-Methode verwenden (z. B. watchTrades -> unWatchTrades).
Inkrementelle Datenstrukturen
In vielen Fällen muss die auf der Client-Seite lauschende Anwendung aufgrund der unidirektionalen Natur der zugrundeliegenden Datenfeeds einen lokalen Snapshot der Daten im Speicher halten und die von der Börse empfangenen Updates in den lokalen Snapshot einarbeiten. Die von der Börse eingehenden Updates werden auch häufig als Deltas bezeichnet, da diese Updates in den meisten Fällen nur die Änderungen zwischen zwei Datenzuständen enthalten und keine unveränderten Daten beinhalten, was das lokale Caching des aktuellen Zustands S aller relevanten Datenobjekte erforderlich macht.
All diese Funktionalität wird von CCXT Pro für den Benutzer übernommen. Um mit CCXT Pro zu arbeiten, muss der Benutzer keine Abonnements und zugehörigen Daten verfolgen oder verwalten. CCXT Pro hält einen Cache von Strukturen im Speicher, um den zugrundeliegenden Aufwand zu bewältigen.
Jedes eingehende Update gibt an, welche Teile der Daten sich geändert haben, und die Empfängerseite „inkrementiert" den lokalen Zustand S, indem sie das Update auf den aktuellen Zustand S anwendet und zum nächsten lokalen Zustand S' übergeht. Im Sinne von CCXT Pro wird dies als „inkrementeller Zustand" bezeichnet, und die Strukturen, die am Prozess des Speicherns und Aktualisierens des gecachten Zustands beteiligt sind, werden als „inkrementelle Strukturen" bezeichnet. CCXT Pro führt mehrere neue Basisklassen ein, um den inkrementellen Zustand bei Bedarf zu behandeln.
Die inkrementellen Strukturen, die von den einheitlichen Methoden von CCXT Pro zurückgegeben werden, sind häufig einer von zwei Typen:
- JSON-dekodiertes Objekt (
objectin JavaScript,dictin Python,array()in PHP). Dieser Typ kann von öffentlichen und privaten Methoden wiewatchOrderBook,watchTicker,watchBalance,watchOrderusw. zurückgegeben werden. - Ein Array/eine Liste von Objekten (üblicherweise in chronologischer Reihenfolge sortiert). Dieser Typ kann von Methoden wie
watchOHLCV,watchTrades,watchMyTrades,watchOrdersusw. zurückgegeben werden.
Die einheitlichen Methoden, die Arrays zurückgeben, wie watchOHLCV, watchTrades, watchMyTrades, watchOrders, basieren auf der Caching-Schicht. Der Benutzer muss die innere Funktionsweise der Caching-Schicht verstehen, um effizient damit arbeiten zu können.
Der Cache ist eine Deque (Double-Ended Queue) mit fester Größe, also ein Array/eine Liste mit zwei Enden. Die CCXT Pro-Bibliothek hat ein vernünftiges Limit für die Anzahl der im Speicher gespeicherten Objekte. Standardmäßig speichern die Caching-Array-Strukturen bis zu 1000 Einträge jedes Typs (1000 neueste Trades, 1000 neueste Kerzen, 1000 neueste Orders). Die zulässige Höchstanzahl kann vom Benutzer bei der Instanziierung oder später konfiguriert werden:
ccxtpro.binance({
'options': {
'tradesLimit': 1000,
'OHLCVLimit': 1000,
'ordersLimit': 1000,
},
})
# or
exchange.options['tradesLimit'] = 1000
exchange.options['OHLCVLimit'] = 1000
exchange.options['ordersLimit'] = 1000Die Cache-Limits müssen vor dem Aufruf von Watch-Methoden gesetzt werden und können während eines Programmlaufs nicht geändert werden.
Wenn noch Platz im Cache vorhanden ist, werden neue Elemente einfach an dessen Ende angehängt. Wenn nicht genügend Platz für ein neues Element vorhanden ist, wird das älteste Element vom Anfang des Caches gelöscht, um Platz zu schaffen. So wächst der Cache beispielsweise von 0 auf 1000 neueste Trades und verbleibt dann bei maximal 1000 neuesten Trades, wobei die gespeicherten Daten mit jedem neuen Update von der Börse kontinuierlich erneuert werden. Es erinnert an ein gleitendes Rahmenfenster oder eine Schiebetür, die wie unten dargestellt aussieht:
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 frameDer Benutzer kann die Cache-Limits über exchange.options konfigurieren, wie oben gezeigt. Verwechseln Sie die Cache-Limits nicht mit dem Paginierungslimit.
Beachten Sie, dass die Parameter since und limit der datumsbasierten Paginierung eine andere Bedeutung haben und immer innerhalb des gecachten Fensters angewendet werden! Wenn der Benutzer ein since-Argument beim Aufruf von watchTrades() angibt, gibt CCXT Pro alle gecachten Trades mit timestamp >= since zurück. Wenn der Benutzer kein since-Argument angibt, gibt CCXT Pro gecachte Trades ab dem Anfang des gleitenden Fensters zurück. Wenn der Benutzer ein limit-Argument angibt, gibt die Bibliothek bis zu limit Kerzen ab since oder ab dem Anfang des Caches zurück. Aus diesem Grund kann der Benutzer aufgrund der WebSocket-Echtzeitspezifika nicht über den gecachten Rahmen hinaus paginieren.
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)newUpdates-Modus
Wenn Sie immer nur den aktuellsten Trade erhalten möchten, sollten Sie die Exchange mit dem auf true gesetzten newUpdates-Flag instanziieren.
exchange = ccxtpro.binance({'newUpdates': True})
while True:
trades = await exchange.watchTrades (symbol)
print(trades)Der newUpdates-Modus nutzt im Hintergrund weiterhin den gleitenden Cache, jedoch werden dem Benutzer nur die neuen Aktualisierungen geliefert. Dies liegt daran, dass einige Exchanges inkrementelle Strukturen verwenden, weshalb wir einen Cache von Objekten vorhalten müssen, da die Exchange möglicherweise nur Teilinformationen wie Statusaktualisierungen liefert.
Das Ergebnis aus dem newUpdates-Modus enthält eine oder mehrere Aktualisierungen, die seit dem letzten Auflösen von exchange.watchMethod aufgetreten sind. CCXT Pro kann eine oder mehrere Orders zurückgeben, die seit dem vorherigen Aufruf aktualisiert wurden. Das Ergebnis des Aufrufs von exchange.watchOrders sieht wie folgt aus:
[
order, // see /docs/manual#order-structure
order,
order,
...
]Hinweis zur Veraltung: In Zukunft wird newUpdates: true der Standardmodus sein, und Sie müssen newUpdates auf false setzen, um den gleitenden Cache zu erhalten.
const ccxtpro = require ('ccxt').pro
console.log ('CCXT version', ccxtpro.version)
console.log ('Supported exchanges:', ccxtpro.exchanges)Das importierte CCXT Pro-Modul kapselt CCXT in sich selbst – jede über CCXT Pro instanziierte Exchange verfügt über alle CCXT-Methoden sowie die zusätzliche Funktionalität.
Instanziierung
CCXT Pro ist für die async/await-Syntax ausgelegt und stützt sich stark auf asynchrone Primitiven wie Promises und Futures.
Das Erstellen einer CCXT Pro Exchange-Instanz ist nahezu identisch mit dem Erstellen einer CCXT Exchange-Instanz.
const ccxt = require ('ccxt').pro
const exchange = new ccxtpro.binance ({ newUpdates: false })Python
Die Python-Implementierung von CCXT Pro basiert auf dem eingebauten asyncio und insbesondere auf der Event Loop. In Python ist es möglich, eine asyncio Event-Loop-Instanz als Konstruktorargument zu übergeben, wie unten gezeigt (identisch mit 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
In PHP werden die asynchronen Primitiven von ReactPHP übernommen. Die PHP-Implementierung von CCXT Pro basiert insbesondere auf Promise und EventLoop. In PHP muss der Benutzer eine ReactPHP Event-Loop-Instanz als Konstruktorargument übergeben, wie unten gezeigt:
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));
}
}Exchange-Eigenschaften
Jede CCXT Pro-Instanz enthält alle Eigenschaften der zugrundeliegenden CCXT-Instanz. Neben den Standard-CCXT-Eigenschaften enthält die CCXT Pro-Instanz folgende zusätzliche Eigenschaften:
{
'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
...
}Unified API
Die Unified CCXT Pro API fördert direkten Kontrollfluss für besseren Codestil, besser lesbaren und architektonisch überlegenen Code im Vergleich zur Verwendung von EventEmittern und Callbacks. Letzteres gilt heute als veralteter Ansatz, da es eine Umkehrung der Kontrolle erfordert (Menschen sind an umgekehrtes Denken nicht gewöhnt).
CCXT Pro verfolgt den modernen Ansatz und ist für die async-Syntax konzipiert. Intern muss CCXT Pro aufgrund der Abhängigkeiten und WebSocket-Bibliotheken, die keine andere Möglichkeit haben, manchmal noch auf umgekehrten Kontrollfluss zurückgreifen.
Das gilt nicht nur für JS/ES6, sondern auch für asynchronen Python-3-Code. In PHP werden die asynchronen Primitiven von ReactPHP übernommen.
Moderne async-Syntax erlaubt es, die Ausführung in parallele Pfade aufzuteilen und anschließend zusammenzuführen, zu gruppieren, zu priorisieren und vieles mehr. Mit Promises lässt sich problemlos zwischen direktem async-Kontrollfluss und invertiertem Callback-Kontrollfluss hin und her wechseln.
Echtzeit- vs. Drosselungsmodus
CCXT Pro unterstützt zwei Modi für Tick-Funktionsschleifen – den Echtzeitmodus und den Drosselungsmodus. Beide werden unten in Pseudocode dargestellt:
// 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
}Im Echtzeitmodus gibt CCXT Pro das Ergebnis zurück, sobald jedes neue Delta von der Exchange eintrifft. Die allgemeine Logik eines einheitlichen Aufrufs in einer Echtzeit-Schleife besteht darin, auf das nächste Delta zu warten und das einheitliche Ergebnis sofort und immer wieder an den Benutzer zurückzugeben. Dies ist nützlich, wenn die Reaktionszeit entscheidend ist oder so schnell wie möglich sein muss.
Der Echtzeitmodus erfordert jedoch Programmiererfahrung mit asynchronen Abläufen, wenn es darum geht, mehrere parallele Tick-Schleifen zu synchronisieren. Darüber hinaus können Exchanges in Phasen hoher Aktivität oder hoher Volatilität eine sehr große Anzahl von Aktualisierungen streamen. Der Entwickler eines Echtzeit-Algorithmus muss daher sicherstellen, dass der Userland-Code in der Lage ist, diese Daten so schnell zu verarbeiten. Das Arbeiten im Echtzeitmodus kann manchmal ressourcenintensiver sein.
Im Drosselungsmodus empfängt und verwaltet CCXT Pro die Daten im Hintergrund. Der Benutzer ist dafür verantwortlich, die Ergebnisse bei Bedarf gelegentlich abzurufen. Die allgemeine Logik der Drosselungsschleife besteht darin, die meiste Zeit zu schlafen und gelegentlich aufzuwachen, um die Ergebnisse zu überprüfen. Dies geschieht in der Regel mit einer festen Frequenz oder „Bildrate". Der Code innerhalb einer Drosselungsschleife lässt sich oft leichter über mehrere Exchanges hinweg synchronisieren. Die Rationierung der in einer gedrosselten Schleife verbrachten Zeit trägt auch dazu bei, den Ressourcenverbrauch auf ein Minimum zu reduzieren. Dies ist praktisch, wenn Ihr Algorithmus aufwändig ist und Sie die Ausführung präzise steuern möchten, um eine zu häufige Ausführung zu vermeiden.
Der offensichtliche Nachteil des Drosselungsmodus ist eine geringere Reaktionsfähigkeit auf Aktualisierungen. Wenn ein Handelsalgorithmus eine bestimmte Anzahl von Millisekunden warten muss, bevor er ausgeführt wird, können ein oder zwei Aktualisierungen früher eintreffen, als diese Zeit abläuft. Im Drosselungsmodus prüft der Benutzer diese Aktualisierungen erst beim nächsten Aufwachen (Schleifeniteration), sodass die Reaktionsverzögerung im Laufe der Zeit innerhalb einer bestimmten Anzahl von Millisekunden variieren kann.
Öffentliche Methoden
watchOrderBook
Die Schnittstelle von watchOrderBook ist identisch mit fetchOrderBook. Sie akzeptiert drei Argumente:
symbol– String, ein einheitliches CCXT-Symbol, erforderlichlimit– Integer, die maximale Anzahl zurückgegebener Geld-/Briefkurse, optionalparams– assoziatives Dictionary, optionale Überschreibungen wie unter Overriding Unified API Params beschrieben
Im Allgemeinen lassen sich Exchanges in zwei Kategorien einteilen:
- Exchanges, die begrenzte Orderbücher unterstützen (nur den oberen Teil des Orderstapels streamen)
- Exchanges, die ausschließlich vollständige Orderbücher streamen
Wenn die Exchange ein Begrenzungsargument akzeptiert, wird das limit-Argument beim Abonnieren des Orderbuch-Streams über eine WebSocket-Verbindung an die Exchange gesendet. Die Exchange sendet dann nur die angegebene Anzahl von Orders, was dazu beiträgt, den Datenverkehr zu reduzieren. Einige Exchanges akzeptieren möglicherweise nur bestimmte Werte für limit, wie 10, 25, 50, 100 usw.
Wenn die zugrundeliegende Exchange kein Begrenzungsargument akzeptiert, erfolgt die Begrenzung auf der Client-Seite.
Das limit-Argument garantiert nicht, dass die Anzahl der Geld- oder Briefkurse immer gleich limit ist. Es bezeichnet die Obergrenze oder das Maximum, sodass zu einem bestimmten Zeitpunkt weniger als limit Geld- oder Briefkurse vorhanden sein können, jedoch niemals mehr als limit. Dies ist der Fall, wenn die Exchange nicht genügend Orders im Orderbuch hat oder wenn eine der obersten Orders im Orderbuch gehandelt und aus dem Orderbuch entfernt wird, wodurch auf der Geld- oder Briefkursseite weniger als limit Einträge verbleiben. Der freie Platz im Orderbuch wird in der Regel schnell mit neuen Daten gefüllt.
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
Ähnlich wie watchOrderBook, akzeptiert jedoch ein Array von Symbolen, sodass Sie mehrere Orderbücher in einer einzigen Nachricht abonnieren können.
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
Einige Exchanges erlauben verschiedene Topics zum Beobachten von Tickern (z. B.: bookTicker). Dies kann in exchange.options['watchTicker']['name'] eingestellt werden.
// 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 eif ($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
Ein weit verbreitetes Missverständnis über WebSockets ist, dass WS-OHLCV-Streams eine Handelsstrategie irgendwie beschleunigen können. Wenn der Zweck Ihrer Anwendung darin besteht, OHLCV-Handel oder eine spekulative algorithmische Strategie zu implementieren, beachten Sie Folgendes sorgfältig.
Im Allgemeinen gibt es zwei Arten von Handelsdaten, die in Algorithmen verwendet werden:
- Erstrangige Echtzeit-Daten wie Orderbücher und Trades
- Zweitrangige nicht-Echtzeit-Daten wie Ticker, OHLCVs usw.
Wenn Entwickler von „Echtzeit" sprechen, meinen sie damit in der Regel Pseudo-Echtzeit oder, einfach ausgedrückt, „so schnell und so nah an Echtzeit wie möglich".
Die zweitrangigen Daten werden immer aus den erstrangigen Daten berechnet. OHLCVs werden aus aggregierten Trades berechnet. Ticker werden aus Trades und Orderbüchern berechnet.
Einige Exchanges berechnen OHLCVs (zweitrangige Daten) für Sie auf der Exchange-Seite und senden Ihnen Aktualisierungen über WS (Binance). Andere Exchanges halten das aus gutem Grund nicht für notwendig.
Offensichtlich braucht die Berechnung zweitrangiger OHLCV-Kerzen aus Trades Zeit. Darüber hinaus braucht auch das Zurücksenden der berechneten Kerze an alle verbundenen Benutzer Zeit. Zusätzliche Verzögerungen können in Phasen hoher Volatilität auftreten, wenn eine Exchange bei hoher Last sehr aktiv gehandelt wird.
Es gibt keine strikte Garantie dafür, wie lange es dauert, bis die Exchange die zweitrangigen Daten berechnet und über WS an Sie überträgt. Die Verzögerungen bei OHLCV-Kerzen können von Exchange zu Exchange erheblich variieren. Beispielsweise kann eine Exchange eine OHLCV-Aktualisierung ~30 Sekunden nach dem tatsächlichen Schließen eines entsprechenden Zeitraums senden. Andere Exchanges können die aktuellen OHLCV-Aktualisierungen in regelmäßigen Abständen senden (z. B. einmal alle 100 ms), während Trades in der Realität viel häufiger stattfinden können.
Die meisten Menschen nutzen WS, um jegliche Art von Verzögerungen zu vermeiden und Echtzeit-Daten zu haben. In den meisten Fällen ist es daher viel besser, nicht auf die Exchange zu warten. Die eigene Neuberechnung der zweitrangigen Daten aus den erstrangigen Daten kann viel schneller sein und unnötige Verzögerungen reduzieren. Deshalb macht es wenig Sinn, WS nur zum Beobachten von OHLCV-Kerzen von der Exchange zu verwenden. Entwickler würden eher watch_trades() verwenden und die OHLCV-Kerzen mit den eingebauten CCXT-Methoden wie build_ohlcvc() neu berechnen.
# 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 eDas erklärt, warum einige Exchanges vernünftigerweise der Meinung sind, dass OHLCVs im WS-Kontext nicht notwendig sind, da Benutzer diese Informationen im Userland viel schneller berechnen können, wenn sie nur einen WS-Stream von Echtzeit-erstrangigen Trades haben.
Wenn Ihre Anwendung nicht sehr zeitkritisch ist, können Sie sich dennoch für charttechnische Zwecke bei OHLCV-Streams anmelden. Wenn die zugrundeliegende exchange.has['watchOHLCV'] gesetzt ist, können Sie watchOHLCV()/watch_ohlcv() wie folgt verwenden:
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
Ähnlich wie watchOHLCV, ermöglicht jedoch mehrere Abonnements von Symbolen und Zeitrahmen
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
Ähnlich wie watchTrades, ermöglicht jedoch das Abonnieren mehrerer Symbole in einem einzigen Aufruf.
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
}
}
}Private Methoden
In den meisten Fällen wird die Authentifizierungslogik von CCXT übernommen, da die Exchanges dieselben Schlüsselpaare und Signaturalgorithmen für REST-APIs und WebSocket-APIs verwenden. Weitere Details finden Sie unter API Keys Setup.
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
Beobachtet alle offenen Positionen und gibt eine Liste von Positions-Strukturen zurück
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)Benutzerdefinierter Handler
Wenn Sie Zugriff auf eingehende Rohnachrichten haben und eigene Handler verwenden möchten, können Sie die handleMessage/handle_message-Methode der Börse überschreiben, zum Beispiel:
A) Durch Vererbung:
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) Durch Überschreiben der Methode:
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');Fehlerbehandlung
Im Fehlerfall wirft CCXT Pro eine Standard-CCXT-Ausnahme. Weitere Details finden Sie unter Fehlerbehandlung.

























