CCXT Pro 매뉴얼
CCXT Pro는 WebSocket 스트리밍 지원을 추가하는 CCXT의 무료 파트입니다: https://github.com/ccxt/ccxt/issues/15171
매뉴얼
CCXT Pro는 WebSocket 스트리밍 지원을 추가하는 CCXT의 무료 파트입니다: https://github.com/ccxt/ccxt/issues/15171
CCXT Pro 스택은 CCXT를 기반으로 구축되었으며, 다음을 사용하여 핵심 CCXT 클래스를 확장합니다:
- JavaScript 프로토타입 수준 믹스인
- Python 다중 상속
- PHP 트레이트
- Java 클래스 상속 (pro 거래소 클래스가 기본 거래소 클래스를 확장)
CCXT Pro는 다국어 지원을 위해 CCXT의 트랜스파일러에 크게 의존합니다.
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 |
| |
+=============================================================+거래소
CCXT Pro 라이브러리는 현재 다음 74개의 암호화폐 거래소 마켓과 WebSocket 트레이딩 API를 지원합니다:이것은 WebSockets API를 지원하는 CCXT Pro의 거래소 목록입니다. 이 목록은 정기적으로 새로운 거래소가 추가되어 업데이트될 예정입니다.
REST를 통해 CCXT에서 사용 가능한 전체 거래소 목록: 지원되는 암호화폐 거래소 시장.
사용법
- 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사전 요건
CCXT Pro를 이해하는 가장 좋은 방법은 전체 CCXT 매뉴얼을 충분히 숙지하고 표준 CCXT를 먼저 실습하는 것입니다. CCXT Pro는 CCXT에서 많은 부분을 차용합니다. 두 라이브러리는 다음을 포함하여 많은 공통점을 공유합니다:
- 공개 API 및 비공개 인증 API의 개념
- 시장, 심볼, 통화 코드 및 ID
- 통합 데이터 구조 및 형식, 오더북, 거래, 주문, 캔들, 타임프레임, ...
- 예외 및 오류 매핑
- 인증 및 API 키 (비공개 피드 및 호출용)
- 구성 옵션
CCXT Pro의 대상 사용자는 주로 전문 알고리즘 트레이더와 개발자로 구성됩니다. 이 라이브러리를 효율적으로 사용하려면 스트리밍 개념에 대해 충분히 숙지해야 합니다. 연결 기반 스트리밍 API(WebSocket, CCXT Pro)와 요청-응답 기반 API(REST, CCXT) 간의 근본적인 차이를 이해해야 합니다.
CCXT 애플리케이션의 일반적인 비동기 스타일 흐름은 다음과 같습니다:
// 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
}
}CCXT Pro에서 fetch* 접두사를 가진 각 공개 및 비공개 통합 RESTful 메서드는 다음과 같이 watch* 접두사가 붙은 스트림 기반 대응 메서드를 가집니다:
- 공개 API
fetchStatus→watchStatusfetchOrderBook→watchOrderBookfetchOrderBookForSymbols→watchOrderBookForSymbolsfetchTicker→watchTickerfetchTickers→watchTickersfetchOHLCV→watchOHLCVfetchOHLCVForSymbols→watchOHLCVForSymbolsfetchTrades→watchTradesfetchTradesForSymbols→watchTradesForSymbolsfetchBidsAsks→watchBidsAsksfetchLiquidations→watchLiquidationsfetchLiquidationsForSymbols→watchLiquidationsForSymbols
- 비공개 API
fetchBalance→watchBalancefetchOrders→watchOrdersfetchOrdersForSymbols→watchOrdersForSymbolsfetchMyTrades→watchMyTradesfetchPosition→watchPositionfetchPositions→watchPositionsfetchLiquidations→watchLiquidationsfetchMyLiquidations→watchMyLiquidationsfetchMyLiquidationsForSymbols→watchMyLiquidationsForSymbolsfetchFundingRates→watchFundingRates
- REST 대안
fetchTrades→fetchTradesWscreateOrder→createOrderWseditOrder→editOrderWscancelOrder→cancelOrderWscancelOrders→cancelOrdersWscancelAllOrders→cancelAllOrdersWs- 기타 ...
- unWatch (
watch메서드의 백그라운드 구독을 중지)unWatchOrderBookunWatchOrderBooksForSymbolsunWatchTradesunWatchTradesForSymbolsunWatchOHLCVForSymbolsunWatchOrderBookForSymbolsunWatchPositionsunWatchTickersunWatchMyTradesunWatchTickerunWatchOHLCVunWatchOrders
통합 CCXT Pro 스트리밍 API는 마이그레이션을 쉽게 하기 위해 CCXT 사용 패턴을 상속합니다.
CCXT Pro 애플리케이션의 일반적인 비동기 스타일 흐름(위의 CCXT 애플리케이션과 대비하여)은 아래에 나와 있습니다:
// 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
}
}이 사용 패턴은 일반적으로 _"tick() 함수"_라고 불리는 핵심 비즈니스 로직 메서드로 래핑됩니다. 이는 수신 이벤트(일명 틱)에 대한 반응을 반복하기 때문입니다. 위의 두 예시에서 CCXT Pro와 CCXT의 일반적인 사용 패턴이 동일하다는 것이 명백합니다.
CCXT의 많은 규칙과 개념이 CCXT Pro에도 적용됩니다:
- CCXT Pro는 통합 API 메서드에 대한 첫 번째 호출 시 시장을 로드하고 캐시합니다
- CCXT Pro는 필요한 경우 내부적으로 CCXT RESTful 메서드를 호출합니다
- CCXT Pro는 필요한 경우 표준 CCXT 예외를 발생시킵니다
- ...
스트리밍 특이 사항
수많은 공통점에도 불구하고, 스트리밍 기반 API는 연결 기반 특성으로 인해 고유한 특이 사항을 가집니다.
연결 기반 인터페이스를 갖는다는 것은 연결 처리 메커니즘을 의미합니다. 연결은 CCXT Pro에 의해 사용자에게 투명하게 관리됩니다. 각 거래소 인스턴스는 자체 연결 세트를 관리합니다.
어떤 watch*() 메서드에 대한 첫 번째 호출 시, 라이브러리는 거래소의 특정 스트림/리소스에 연결을 수립하고 이를 유지합니다. 연결이 이미 존재하는 경우 재사용됩니다. 라이브러리는 구독 요청/응답 메시징 시퀀스를 처리하며, 요청된 스트림이 비공개인 경우 인증/서명도 처리합니다.
라이브러리는 또한 업링크 상태를 감시하고 연결을 유지합니다. 심각한 예외, 연결 해제 또는 연결 타임아웃/실패 시, tick 함수의 다음 반복에서 watch 메서드를 호출하여 재연결을 트리거합니다. 이 방식으로 라이브러리는 사용자에게 투명하게 연결 해제 및 재연결을 처리합니다. CCXT Pro는 필요한 속도 제한 및 지수 백오프 재연결 지연을 적용합니다. 이 모든 기능은 기본적으로 활성화되어 있으며 거래소 속성을 통해 평소처럼 구성할 수 있습니다.
대부분의 거래소는 스트리밍 API를 위한 단일 기본 URL만 가집니다(일반적으로 ws:// 또는 wss://로 시작하는 WebSocket). 일부는 문제의 피드에 따라 각 스트림에 대해 두 개 이상의 URL을 가질 수 있습니다.
거래소의 스트리밍 API는 두 가지 다른 범주로 분류할 수 있습니다:
- sub 또는 subscribe는 수신만 허용
- pub 또는 publish는 송수신 허용
Sub
sub 인터페이스는 일반적으로 데이터 스트림을 구독하고 청취하는 것을 허용합니다. WebSocket을 지원하는 대부분의 거래소는 sub 유형의 API만 제공합니다. sub 유형에는 공개 시장 데이터 스트리밍이 포함됩니다. 때로는 거래소가 비공개 사용자 데이터 구독도 허용합니다. 사용자가 데이터 피드를 구독하면 채널은 거래소에서 사용자에게 지속적으로 업데이트를 전송하는 단방향 작동을 시작합니다.
일반적으로 나타나는 공개 데이터 스트림의 유형:
- 오더북 (가장 일반적) - 추가, 편집 및 삭제된 주문에 대한 업데이트 (일명 변경 델타)
- 24시간 통계 변경 시 티커 업데이트
- 체결 피드 (또한 일반적) - 공개 거래의 실시간 스트림
- OHLCV 캔들스틱 피드
- 하트비트
- 거래소 채팅/트롤박스
덜 일반적인 비공개 사용자 데이터 스트림의 유형:
- 사용자의 비공개 거래 스트림
- 실시간 주문 업데이트
- 잔액 업데이트
- 사용자 정의 스트림
- 거래소별 및 기타 스트림
Pub
pub 인터페이스는 일반적으로 사용자가 서버로 데이터 요청을 보낼 수 있도록 허용합니다. 이는 일반적으로 다음과 같은 일반적인 사용자 작업을 포함합니다:
- 주문 배치
- 주문 취소
- 출금 요청 배치
- 채팅/트롤박스 메시지 게시
- 기타
일부 거래소는 pub WS API를 제공하지 않으며 sub WS API만 제공합니다. 그러나 완전한 스트리밍 API를 갖춘 거래소도 있습니다. 대부분의 경우 사용자는 스트리밍 API만으로는 효과적으로 운영할 수 없습니다. 거래소는 공개 시장 데이터를 sub으로 스트리밍하고, REST API는 누락된 pub 부분에 여전히 필요합니다.
unWatch
각 watchX 메서드는 스트림과의 구독을 수립하고 거래소로부터 지속적으로 업데이트를 받습니다. watchX 메서드에서 반환 값을 받는 것을 중지하더라도 스트림은 계속 전송하며 이는 백그라운드에서 처리되고 저장됩니다. 이러한 백그라운드 구독을 중지하려면 unWatch 메서드를 사용해야 합니다(예: watchTrades -> unWatchTrades).
증분 데이터 구조
많은 경우 기반 데이터 피드의 단방향 특성으로 인해, 클라이언트 측에서 수신하는 애플리케이션은 메모리에 데이터의 로컬 스냅샷을 유지하고 거래소 서버에서 받은 업데이트를 로컬 스냅샷에 병합해야 합니다. 거래소에서 오는 업데이트는 종종 _델타_라고도 불립니다. 왜냐하면 대부분의 경우 이러한 업데이트는 두 데이터 상태 간의 변경 사항만 포함하고 변경되지 않은 데이터는 포함하지 않아, 모든 관련 데이터 객체의 현재 상태 S를 로컬에 캐시하여 저장해야 하기 때문입니다.
이 모든 기능은 CCXT Pro가 사용자를 위해 처리합니다. CCXT Pro로 작업하기 위해 사용자는 구독 및 관련 데이터를 추적하거나 관리할 필요가 없습니다. CCXT Pro는 기반의 번거로움을 처리하기 위해 메모리에 구조 캐시를 유지합니다.
각 수신 업데이트는 데이터의 어느 부분이 변경되었는지를 나타내며, 수신 측은 현재 상태 S 위에 업데이트를 병합하여 로컬 상태 S를 "증분"하고 다음 로컬 상태 S'로 이동합니다. CCXT Pro 용어로 이것을 _"증분 상태"_라고 하며, 캐시된 상태를 저장하고 업데이트하는 과정에 관여하는 구조를 _"증분 구조"_라고 합니다. CCXT Pro는 필요한 경우 증분 상태를 처리하기 위해 여러 새로운 기본 클래스를 도입합니다.
CCXT Pro의 통합 메서드에서 반환되는 증분 구조는 일반적으로 두 가지 유형 중 하나입니다:
- JSON 디코딩된 객체 (JavaScript의
object, Python의dict, PHP의array()). 이 유형은watchOrderBook,watchTicker,watchBalance,watchOrder등과 같은 공개 및 비공개 메서드에서 반환될 수 있습니다. - 객체의 배열/목록 (일반적으로 시간순으로 정렬). 이 유형은
watchOHLCV,watchTrades,watchMyTrades,watchOrders등과 같은 메서드에서 반환될 수 있습니다.
watchOHLCV, watchTrades, watchMyTrades, watchOrders와 같이 배열을 반환하는 통합 메서드는 캐싱 레이어를 기반으로 합니다. 사용자는 효율적으로 작업하기 위해 캐싱 레이어의 내부 작동 방식을 이해해야 합니다.
캐시는 양쪽 끝을 가진 고정 크기 데크(deque), 즉 배열/목록입니다. CCXT Pro 라이브러리는 메모리에 저장되는 객체 수에 합리적인 제한이 있습니다. 기본적으로 캐싱 배열 구조는 각 유형별로 최대 1000개의 항목을 저장합니다(최근 거래 1000개, 최근 캔들 1000개, 최근 주문 1000개). 허용되는 최대 수는 인스턴스화 시 또는 이후에 사용자가 구성할 수 있습니다:
ccxtpro.binance({
'options': {
'tradesLimit': 1000,
'OHLCVLimit': 1000,
'ordersLimit': 1000,
},
})
# or
exchange.options['tradesLimit'] = 1000
exchange.options['OHLCVLimit'] = 1000
exchange.options['ordersLimit'] = 1000캐시 제한은 watch 메서드를 호출하기 전에 설정해야 하며 프로그램 실행 중에는 변경할 수 없습니다.
캐시에 공간이 남아 있으면 새 요소는 단순히 끝에 추가됩니다. 새 요소를 수용할 공간이 충분하지 않으면 공간을 확보하기 위해 캐시의 시작 부분에서 가장 오래된 요소가 삭제됩니다. 따라서, 예를 들어, 캐시는 0에서 최근 거래 1000개로 성장한 다음 최대 최근 거래 1000개를 유지하면서 거래소에서 들어오는 각 새 업데이트로 저장된 데이터를 지속적으로 갱신합니다. 이는 아래와 같이 보이는 슬라이딩 프레임 창 또는 슬라이딩 도어를 연상시킵니다:
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사용자는 위에서 보여준 것처럼 exchange.options를 사용하여 캐시 제한을 구성할 수 있습니다. 캐시 제한을 페이지네이션 제한과 혼동하지 마십시오.
참고: since 및 limit 날짜 기반 페이지네이션 파라미터는 다른 의미를 가지며 항상 캐시된 창 내에서 적용됩니다! 사용자가 watchTrades() 호출에 since 인수를 지정하면, CCXT Pro는 timestamp >= since인 모든 캐시된 거래를 반환합니다. 사용자가 since 인수를 지정하지 않으면, CCXT Pro는 슬라이딩 창의 시작부터 캐시된 거래를 반환합니다. 사용자가 limit 인수를 지정하면, 라이브러리는 since 또는 캐시의 시작부터 최대 limit개의 캔들을 반환합니다. 이런 이유로 사용자는 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)newUpdates 모드
항상 가장 최근의 거래만 받고 싶다면, newUpdates 플래그를 true로 설정하여 거래소를 인스턴스화해야 합니다.
exchange = ccxtpro.binance({'newUpdates': True})
while True:
trades = await exchange.watchTrades (symbol)
print(trades)newUpdates 모드는 백그라운드에서 슬라이딩 캐시를 계속 활용하지만, 사용자에게는 새로운 업데이트만 제공됩니다. 일부 거래소는 증분 구조를 사용하므로, 거래소가 상태 업데이트와 같은 부분 정보만 제공할 수 있기 때문에 객체의 캐시를 유지해야 합니다.
newUpdates 모드의 결과는 마지막으로 exchange.watchMethod가 해결된 이후 발생한 하나 이상의 업데이트입니다. CCXT Pro는 이전 호출 이후 업데이트된 하나 이상의 주문을 반환할 수 있습니다. exchange.watchOrders를 호출한 결과는 아래와 같습니다:
[
order, // see /docs/manual#order-structure
order,
order,
...
]지원 중단 경고: 앞으로 newUpdates: true가 기본 모드가 될 것이며, 슬라이딩 캐시를 사용하려면 newUpdates를 false로 설정해야 합니다.
const ccxtpro = require ('ccxt').pro
console.log ('CCXT version', ccxtpro.version)
console.log ('Supported exchanges:', ccxtpro.exchanges)가져온 CCXT Pro 모듈은 내부에 CCXT를 래핑합니다 – CCXT Pro를 통해 인스턴스화된 모든 거래소는 CCXT의 모든 메서드와 추가 기능을 갖습니다.
인스턴스화
CCXT Pro는 async/await 스타일 문법을 위해 설계되었으며, 프로미스와 퓨처와 같은 비동기 기본 요소에 크게 의존합니다.
CCXT Pro 거래소 인스턴스를 생성하는 것은 CCXT 거래소 인스턴스를 생성하는 것과 거의 동일합니다.
const ccxt = require ('ccxt').pro
const exchange = new ccxtpro.binance ({ newUpdates: false })Python
CCXT Pro의 Python 구현은 내장된 asyncio와 특히 Event Loop에 의존합니다. Python에서는 아래와 같이 생성자 인수에 asyncio의 이벤트 루프 인스턴스를 제공할 수 있습니다 (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
PHP에서 비동기 기본 요소는 ReactPHP에서 가져옵니다. CCXT Pro의 PHP 구현은 특히 Promise와 EventLoop에 의존합니다. PHP에서는 아래와 같이 생성자 인수에 ReactPHP의 이벤트 루프 인스턴스를 제공해야 합니다:
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));
}
}거래소 속성
모든 CCXT Pro 인스턴스는 기본 CCXT 인스턴스의 모든 속성을 포함합니다. 표준 CCXT 속성 외에도 CCXT Pro 인스턴스에는 다음이 포함됩니다:
{
'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
통합 CCXT Pro API는 EventEmitter와 콜백을 사용하는 것에 비해 더 나은 코드 스타일, 더 읽기 쉽고 아키텍처적으로 우수한 코드를 위한 직접적인 제어 흐름을 장려합니다. 후자는 제어의 역전을 필요로 하기 때문에 (사람들은 역전된 사고에 익숙하지 않습니다) 현재는 구식 접근법으로 간주됩니다.
CCXT Pro는 현대적인 접근법을 따르며 async 문법을 위해 설계되었습니다. 내부적으로 CCXT Pro는 그렇게 할 수 없는 의존성과 WebSocket 라이브러리 때문에 때때로 역전된 제어 흐름을 사용해야 합니다.
이는 JS/ES6뿐만 아니라 Python 3 async 코드에도 동일하게 적용됩니다. PHP에서 비동기 기본 요소는 ReactPHP에서 가져옵니다.
현대적인 async 문법을 사용하면 실행을 병렬 경로로 결합하고 분리한 다음 병합하고, 그룹화하고, 우선순위를 정하는 등의 작업을 할 수 있습니다. 프로미스를 사용하면 직접적인 async 스타일 제어 흐름에서 역전된 콜백 스타일 제어 흐름으로, 그리고 반대로 쉽게 변환할 수 있습니다.
실시간 vs 스로틀링
CCXT Pro는 두 가지 틱 함수 루프 모드를 지원합니다 – 실시간 모드와 스로틀링 모드. 둘 다 아래 의사코드에 나와 있습니다:
// 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
}실시간 모드에서 CCXT Pro는 거래소에서 각 새로운 델타가 도착하는 즉시 결과를 반환합니다. 실시간 루프에서 통합 호출의 일반적인 논리는 다음 델타를 기다렸다가 즉시 통합 결과 구조를 사용자에게 반환하는 것을 반복하는 것입니다. 이는 반응 시간이 중요하거나 가능한 한 빠르게 해야 할 때 유용합니다.
그러나 실시간 모드는 여러 병렬 틱 루프를 동기화할 때 async 흐름에 대한 프로그래밍 경험을 필요로 합니다. 그 외에도 거래소는 높은 활동이나 높은 변동성 기간 동안 매우 많은 수의 업데이트를 스트리밍할 수 있습니다. 따라서 실시간 알고리즘을 개발하는 사용자는 사용자 코드가 그렇게 빠른 데이터를 소비할 수 있는지 확인해야 합니다. 실시간 모드에서 작업하는 것은 때때로 리소스에 더 많은 부담을 줄 수 있습니다.
스로틀링 모드에서 CCXT Pro는 백그라운드에서 데이터를 수신하고 관리합니다. 사용자는 필요할 때 가끔 결과를 직접 호출해야 합니다. 스로틀링 루프의 일반적인 논리는 대부분의 시간 동안 잠자다가 가끔 결과를 확인하기 위해 깨어나는 것입니다. 이는 보통 일정한 주파수, 즉 _"프레임 레이트"_로 수행됩니다. 스로틀링 루프 내의 코드는 여러 거래소에 걸쳐 동기화하기가 더 쉬운 경우가 많습니다. 스로틀링 루프에서 소비되는 시간의 배분은 리소스 사용량을 최소화하는 데도 도움이 됩니다. 이는 알고리즘이 무겁고 너무 자주 실행되는 것을 피하기 위해 실행을 정확하게 제어하려는 경우에 유용합니다.
스로틀링 모드의 명백한 단점은 업데이트에 대한 반응성이나 응답성이 낮다는 것입니다. 거래 알고리즘이 실행되기 전에 일정 밀리초를 기다려야 할 때 – 그 시간이 만료되기 전에 하나 또는 두 개의 업데이트가 도착할 수 있습니다. 스로틀링 모드에서 사용자는 다음 웨이크업(루프 반복) 시에만 해당 업데이트를 확인하므로, 반응 지연이 시간이 지남에 따라 일정 밀리초 범위 내에서 달라질 수 있습니다.
공개 메서드
watchOrderBook
watchOrderBook의 인터페이스는 fetchOrderBook과 동일합니다. 세 가지 인수를 받습니다:
symbol– 문자열, 통합 CCXT 심볼, 필수limit– 정수, 반환되는 최대 매수/매도 수, 선택 사항params– 연관 딕셔너리, 통합 API 파라미터 재정의에 설명된 선택적 재정의
일반적으로 거래소는 두 가지 범주로 나눌 수 있습니다:
- 제한된 호가창을 지원하는 거래소 (주문 스택의 상위 부분만 스트리밍)
- 전체 호가창만 스트리밍하는 거래소
거래소가 제한 인수를 받는 경우, limit 인수는 WebSocket 연결을 통해 호가창 스트림에 구독할 때 거래소로 전송됩니다. 그러면 거래소는 지정된 수의 주문만 전송하여 트래픽을 줄이는 데 도움이 됩니다. 일부 거래소는 10, 25, 50, 100 등 특정 limit 값만 허용할 수 있습니다.
기본 거래소가 제한 인수를 받지 않는 경우, 제한은 클라이언트 측에서 수행됩니다.
limit 인수는 매수 또는 매도의 수가 항상 limit와 동일하다는 것을 보장하지 않습니다. 상한선 또는 최대값을 나타내므로, 특정 시점에 limit보다 적은 매수 또는 매도가 있을 수 있지만, limit보다 많은 매수 또는 매도는 없습니다. 이는 거래소에 호가창에 충분한 주문이 없거나, 호가창의 상위 주문 중 하나가 체결되어 호가창에서 제거되어 매수 또는 매도 측에 limit보다 적은 항목이 남는 경우에 해당합니다. 호가창의 빈 공간은 보통 새 데이터로 빠르게 채워집니다.
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
watchOrderBook과 유사하지만 심볼 배열을 받으므로 단일 메시지로 여러 호가창을 구독할 수 있습니다.
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
일부 거래소는 다양한 토픽(예: bookTicker)으로 티커를 수신하는 것을 허용합니다. 이는 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 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
WebSocket에 대한 매우 일반적인 오해는 WS OHLCV 스트림이 어떻게든 거래 전략의 속도를 높일 수 있다는 것입니다. 앱의 목적이 OHLCV 거래 또는 투기적 알고리즘 전략을 구현하는 것이라면, 다음을 신중하게 고려하십시오.
일반적으로 알고리즘에 사용되는 두 가지 유형의 거래 데이터가 있습니다:
- 호가창 및 거래와 같은 1차 실시간 데이터
- 티커, ohlcv 등과 같은 2차 비실시간 데이터
개발자가 _"실시간"_이라고 말할 때, 그것은 보통 의사 실시간을 의미하거나, 간단히 말해 _"가능한 한 빠르고 실시간에 가깝게"_를 의미합니다.
2차 데이터는 항상 1차 데이터에서 계산됩니다. OHLCV는 집계된 거래에서 계산됩니다. 티커는 거래 및 호가창에서 계산됩니다.
일부 거래소는 거래소 측에서 OHLCV(2차 데이터)를 계산하여 WS를 통해 업데이트를 전송합니다(Binance). 다른 거래소는 그것이 필요하다고 생각하지 않으며, 그 이유가 있습니다.
분명히, 거래에서 2차 OHLCV 캔들을 계산하는 데는 시간이 걸립니다. 그 외에도 계산된 캔들을 연결된 모든 사용자에게 다시 전송하는 데도 시간이 걸립니다. 높은 변동성 기간 동안 거래소가 높은 부하에서 매우 활발하게 거래될 경우 추가 지연이 발생할 수 있습니다.
거래소가 2차 데이터를 계산하고 WS를 통해 스트리밍하는 데 얼마나 걸릴지에 대한 엄격한 보장이 없습니다. OHLCV 캔들의 지연 및 랙은 거래소마다 크게 다를 수 있습니다. 예를 들어, 거래소는 해당 기간의 실제 마감 후 ~30초 후에 OHLCV 업데이트를 보낼 수 있습니다. 다른 거래소는 현재 OHLCV 업데이트를 정기적인 간격(예: 100ms마다)으로 보낼 수 있으며, 실제로는 거래가 훨씬 더 자주 발생할 수 있습니다.
대부분의 사람들은 모든 종류의 지연을 피하고 실시간 데이터를 갖기 위해 WS를 사용합니다. 따라서 대부분의 경우 거래소를 기다리지 않는 것이 훨씬 낫습니다. 1차 데이터에서 직접 2차 데이터를 재계산하는 것이 훨씬 빠를 수 있으며, 불필요한 지연을 줄일 수 있습니다. 따라서 거래소에서 OHLCV 캔들만 감시하기 위해 WS를 사용하는 것은 그다지 의미가 없습니다. 개발자들은 대신 watch_trades()를 사용하고 build_ohlcvc()와 같은 CCXT의 내장 메서드를 사용하여 OHLCV 캔들을 재계산하는 것을 선호합니다.
# 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이것이 왜 일부 거래소가 WS 맥락에서 OHLCV가 필요하지 않다고 합리적으로 생각하는지를 설명합니다. 사용자가 실시간 1차 거래의 WS 스트림만 있으면 사용자 코드에서 해당 정보를 훨씬 빠르게 계산할 수 있기 때문입니다.
애플리케이션이 시간에 크게 민감하지 않다면, 차트 목적으로 OHLCV 스트림에 구독할 수 있습니다. 기본 exchange.has['watchOHLCV']가 있다면, 아래와 같이 watchOHLCV()/watch_ohlcv()를 사용할 수 있습니다:
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
watchOHLCV와 유사하지만 심볼과 타임프레임의 다중 구독을 허용합니다.
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
watchTrades와 유사하지만 단일 호출로 여러 심볼을 구독하는 것을 허용합니다.
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
}
}
}비공개 메서드
대부분의 경우 인증 로직은 거래소가 REST API와 WebSocket API에 동일한 키페어와 서명 알고리즘을 사용하기 때문에 CCXT에서 차용됩니다. 자세한 내용은 API 키 설정을 참조하십시오.
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
모든 열린 포지션을 감시하고 포지션 구조 목록을 반환합니다
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)커스텀 핸들러
수신되는 원시 메시지에 접근하고 커스텀 핸들러를 사용하려면, 거래소의 handleMessage/handle_message 메서드를 다음과 같이 오버라이드할 수 있습니다:
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) 메서드를 직접 오버라이드하는 방법:
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');오류 처리
오류가 발생한 경우 CCXT Pro는 표준 CCXT 예외를 발생시킵니다. 자세한 내용은 오류 처리를 참조하세요.

























